13
13
from typing_extensions import TypeVar , deprecated
14
14
15
15
from pydantic_graph import BaseNode , End , Graph , GraphRun , GraphRunContext
16
- from pydantic_graph .graph import GraphRunResult
17
16
18
17
from . import (
19
18
_agent_graph ,
@@ -215,7 +214,7 @@ async def run(
215
214
usage_limits : _usage .UsageLimits | None = None ,
216
215
usage : _usage .Usage | None = None ,
217
216
infer_name : bool = True ,
218
- ) -> AgentRunResult [AgentDepsT , ResultDataT ]: ...
217
+ ) -> AgentRunResult [ResultDataT ]: ...
219
218
220
219
@overload
221
220
async def run (
@@ -230,7 +229,7 @@ async def run(
230
229
usage_limits : _usage .UsageLimits | None = None ,
231
230
usage : _usage .Usage | None = None ,
232
231
infer_name : bool = True ,
233
- ) -> AgentRunResult [AgentDepsT , RunResultDataT ]: ...
232
+ ) -> AgentRunResult [RunResultDataT ]: ...
234
233
235
234
async def run (
236
235
self ,
@@ -244,7 +243,7 @@ async def run(
244
243
usage_limits : _usage .UsageLimits | None = None ,
245
244
usage : _usage .Usage | None = None ,
246
245
infer_name : bool = True ,
247
- ) -> AgentRunResult [AgentDepsT , Any ]:
246
+ ) -> AgentRunResult [Any ]:
248
247
"""Run the agent with a user prompt in async mode.
249
248
250
249
This method builds an internal agent graph (using system prompts, tools and result schemas) and then
@@ -291,8 +290,8 @@ async def main():
291
290
) as agent_run :
292
291
async for _ in agent_run :
293
292
pass
294
- final_result = agent_run . final_result
295
- assert final_result is not None , 'The graph run should have ended with a final result '
293
+
294
+ assert ( final_result := agent_run . result ) is not None , 'The graph run did not finish properly '
296
295
return final_result
297
296
298
297
@contextmanager
@@ -358,7 +357,7 @@ async def main():
358
357
End(data=FinalResult(data='Paris', tool_name=None)),
359
358
]
360
359
'''
361
- print(agent_run.final_result .data)
360
+ print(agent_run.result .data)
362
361
#> Paris
363
362
```
364
363
@@ -460,7 +459,7 @@ def run_sync(
460
459
usage_limits : _usage .UsageLimits | None = None ,
461
460
usage : _usage .Usage | None = None ,
462
461
infer_name : bool = True ,
463
- ) -> AgentRunResult [AgentDepsT , ResultDataT ]: ...
462
+ ) -> AgentRunResult [ResultDataT ]: ...
464
463
465
464
@overload
466
465
def run_sync (
@@ -475,7 +474,7 @@ def run_sync(
475
474
usage_limits : _usage .UsageLimits | None = None ,
476
475
usage : _usage .Usage | None = None ,
477
476
infer_name : bool = True ,
478
- ) -> AgentRunResult [AgentDepsT , RunResultDataT ]: ...
477
+ ) -> AgentRunResult [RunResultDataT ]: ...
479
478
480
479
def run_sync (
481
480
self ,
@@ -489,7 +488,7 @@ def run_sync(
489
488
usage_limits : _usage .UsageLimits | None = None ,
490
489
usage : _usage .Usage | None = None ,
491
490
infer_name : bool = True ,
492
- ) -> AgentRunResult [AgentDepsT , Any ]:
491
+ ) -> AgentRunResult [Any ]:
493
492
"""Synchronously run the agent with a user prompt.
494
493
495
494
This is a convenience method that wraps [`self.run`][pydantic_ai.Agent.run] with `loop.run_until_complete(...)`.
@@ -1166,8 +1165,8 @@ class AgentRun(Generic[AgentDepsT, ResultDataT]):
1166
1165
You generally obtain an `AgentRun` instance by calling `with my_agent.iter(...) as agent_run:`.
1167
1166
1168
1167
Once you have an instance, you can use it to iterate through the run's nodes as they execute. When an
1169
- [`End`][pydantic_graph.nodes.End] is reached, the run finishes and
1170
- [`final_result`][pydantic_ai.agent.AgentRun.final_result] becomes available.
1168
+ [`End`][pydantic_graph.nodes.End] is reached, the run finishes and [`result`][pydantic_ai.agent.AgentRun.result]
1169
+ becomes available.
1171
1170
1172
1171
Example:
1173
1172
```python
@@ -1207,7 +1206,7 @@ async def main():
1207
1206
End(data=FinalResult(data='Paris', tool_name=None)),
1208
1207
]
1209
1208
'''
1210
- print(agent_run.final_result .data)
1209
+ print(agent_run.result .data)
1211
1210
#> Paris
1212
1211
```
1213
1212
@@ -1240,16 +1239,21 @@ def next_node(
1240
1239
return self ._graph_run .next_node
1241
1240
1242
1241
@property
1243
- def final_result (self ) -> AgentRunResult [AgentDepsT , ResultDataT ] | None :
1242
+ def result (self ) -> AgentRunResult [ResultDataT ] | None :
1244
1243
"""The final result of the run if it has ended, otherwise `None`.
1245
1244
1246
- Once the run returns an [`End`][pydantic_graph.nodes.End] node, `final_result ` is populated
1245
+ Once the run returns an [`End`][pydantic_graph.nodes.End] node, `result ` is populated
1247
1246
with an [`AgentRunResult`][pydantic_ai.agent.AgentRunResult].
1248
1247
"""
1249
- graph_run_result = self ._graph_run .final_result
1248
+ graph_run_result = self ._graph_run .result
1250
1249
if graph_run_result is None :
1251
1250
return None
1252
- return AgentRunResult (graph_run_result )
1251
+ return AgentRunResult (
1252
+ graph_run_result .output .data ,
1253
+ graph_run_result .output .tool_name ,
1254
+ graph_run_result .state ,
1255
+ self ._graph_run .deps .new_message_index ,
1256
+ )
1253
1257
1254
1258
def __aiter__ (
1255
1259
self ,
@@ -1345,7 +1349,7 @@ async def main():
1345
1349
End(data=FinalResult(data='Paris', tool_name=None)),
1346
1350
]
1347
1351
'''
1348
- print('Final result:', agent_run.final_result .data)
1352
+ print('Final result:', agent_run.result .data)
1349
1353
#> Final result: Paris
1350
1354
```
1351
1355
@@ -1364,47 +1368,36 @@ def usage(self) -> _usage.Usage:
1364
1368
"""Get usage statistics for the run so far, including token usage, model requests, and so on."""
1365
1369
return self ._graph_run .state .usage
1366
1370
1367
- def __repr__ (self ):
1368
- final_result = self ._graph_run .final_result
1369
- result_repr = '<run not finished>' if final_result is None else repr (final_result .result )
1370
- kws = [f'result={ result_repr } ' , f'usage={ self .usage ()} ' ]
1371
- return '<{} {}>' .format (type (self ).__name__ , ' ' .join (kws ))
1371
+ def __repr__ (self ) -> str :
1372
+ result = self ._graph_run .result
1373
+ result_repr = '<run not finished>' if result is None else repr (result .output )
1374
+ return f'<{ type (self ).__name__ } result={ result_repr } usage={ self .usage ()} >'
1372
1375
1373
1376
1374
1377
@dataclasses .dataclass
1375
- class AgentRunResult (Generic [AgentDepsT , ResultDataT ]):
1378
+ class AgentRunResult (Generic [ResultDataT ]):
1376
1379
"""The final result of an agent run."""
1377
1380
1378
- _graph_run_result : GraphRunResult [
1379
- _agent_graph .GraphAgentState , _agent_graph .GraphAgentDeps [AgentDepsT , Any ], FinalResult [ResultDataT ]
1380
- ]
1381
-
1382
- @property
1383
- def _result (self ) -> FinalResult [ResultDataT ]:
1384
- return self ._graph_run_result .result
1385
-
1386
- @property
1387
- def data (self ) -> ResultDataT :
1388
- return self ._result .data
1381
+ data : ResultDataT # TODO: rename this to output. I'm putting this off for now mostly to reduce the size of the diff
1389
1382
1390
- @ property
1391
- def _result_tool_name ( self ) -> str | None :
1392
- return self . _result . tool_name
1383
+ _result_tool_name : str | None = dataclasses . field ( repr = False )
1384
+ _state : _agent_graph . GraphAgentState = dataclasses . field ( repr = False )
1385
+ _new_message_index : int = dataclasses . field ( repr = False )
1393
1386
1394
1387
def _set_result_tool_return (self , return_content : str ) -> list [_messages .ModelMessage ]:
1395
1388
"""Set return content for the result tool.
1396
1389
1397
1390
Useful if you want to continue the conversation and want to set the response to the result tool call.
1398
1391
"""
1399
- if not self ._result . tool_name :
1392
+ if not self ._result_tool_name :
1400
1393
raise ValueError ('Cannot set result tool return content when the return type is `str`.' )
1401
- messages = deepcopy (self ._graph_run_result . state .message_history )
1394
+ messages = deepcopy (self ._state .message_history )
1402
1395
last_message = messages [- 1 ]
1403
1396
for part in last_message .parts :
1404
- if isinstance (part , _messages .ToolReturnPart ) and part .tool_name == self ._result . tool_name :
1397
+ if isinstance (part , _messages .ToolReturnPart ) and part .tool_name == self ._result_tool_name :
1405
1398
part .content = return_content
1406
1399
return messages
1407
- raise LookupError (f'No tool call found with tool name { self ._result . tool_name !r} .' )
1400
+ raise LookupError (f'No tool call found with tool name { self ._result_tool_name !r} .' )
1408
1401
1409
1402
def all_messages (self , * , result_tool_return_content : str | None = None ) -> list [_messages .ModelMessage ]:
1410
1403
"""Return the history of _messages.
@@ -1421,7 +1414,7 @@ def all_messages(self, *, result_tool_return_content: str | None = None) -> list
1421
1414
if result_tool_return_content is not None :
1422
1415
return self ._set_result_tool_return (result_tool_return_content )
1423
1416
else :
1424
- return self ._graph_run_result . state .message_history
1417
+ return self ._state .message_history
1425
1418
1426
1419
def all_messages_json (self , * , result_tool_return_content : str | None = None ) -> bytes :
1427
1420
"""Return all messages from [`all_messages`][pydantic_ai.agent.AgentRunResult.all_messages] as JSON bytes.
@@ -1439,10 +1432,6 @@ def all_messages_json(self, *, result_tool_return_content: str | None = None) ->
1439
1432
self .all_messages (result_tool_return_content = result_tool_return_content )
1440
1433
)
1441
1434
1442
- @property
1443
- def _new_message_index (self ) -> int :
1444
- return self ._graph_run_result .deps .new_message_index
1445
-
1446
1435
def new_messages (self , * , result_tool_return_content : str | None = None ) -> list [_messages .ModelMessage ]:
1447
1436
"""Return new messages associated with this run.
1448
1437
@@ -1477,8 +1466,4 @@ def new_messages_json(self, *, result_tool_return_content: str | None = None) ->
1477
1466
1478
1467
def usage (self ) -> _usage .Usage :
1479
1468
"""Return the usage of the whole run."""
1480
- return self ._graph_run_result .state .usage
1481
-
1482
- def __repr__ (self ):
1483
- kws = [f'data={ self .data !r} ' , f'usage={ self .usage ()} ' ]
1484
- return '<{} {}>' .format (type (self ).__name__ , ' ' .join (kws ))
1469
+ return self ._state .usage
0 commit comments