Skip to content

Commit e799024

Browse files
committed
Rename final_result to result and drop DepsT in some places
1 parent 9a676d2 commit e799024

File tree

12 files changed

+94
-105
lines changed

12 files changed

+94
-105
lines changed

Diff for: docs/agents.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ async def main():
144144
End(data=FinalResult(data='Paris', tool_name=None)),
145145
]
146146
"""
147-
print(agent_run.final_result.data)
147+
print(agent_run.result.data)
148148
#> Paris
149149
```
150150

Diff for: docs/graph.md

+11-11
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,11 @@ class Increment(BaseNode): # (2)!
156156

157157

158158
fives_graph = Graph(nodes=[DivisibleBy5, Increment]) # (3)!
159-
graph_run = fives_graph.run_sync(DivisibleBy5(4)) # (4)!
160-
print(graph_run.result)
159+
result = fives_graph.run_sync(DivisibleBy5(4)) # (4)!
160+
print(result.output)
161161
#> 5
162162
# the full history is quite verbose (see below), so we'll just print the summary
163-
print([item.data_snapshot() for item in graph_run.history])
163+
print([item.data_snapshot() for item in result.history])
164164
#> [DivisibleBy5(foo=4), Increment(foo=4), DivisibleBy5(foo=5), End(data=5)]
165165
```
166166

@@ -464,8 +464,8 @@ async def main():
464464
)
465465
state = State(user)
466466
feedback_graph = Graph(nodes=(WriteEmail, Feedback))
467-
graph_run = await feedback_graph.run(WriteEmail(), state=state)
468-
print(graph_run.result)
467+
result = await feedback_graph.run(WriteEmail(), state=state)
468+
print(result.output)
469469
"""
470470
Email(
471471
subject='Welcome to our tech blog!',
@@ -686,7 +686,7 @@ async def main():
686686
#> Node: CountDown()
687687
#> Node: CountDown()
688688
#> Node: End(data=0)
689-
print('Final result:', run.final_result.result) # (3)!
689+
print('Final result:', run.result.output) # (3)!
690690
#> Final result: 0
691691
print('History snapshots:', [step.data_snapshot() for step in run.history])
692692
"""
@@ -724,7 +724,7 @@ async def main():
724724
break # (3)!
725725
node = await run.next(node) # (4)!
726726

727-
print(run.final_result) # (5)!
727+
print(run.result) # (5)!
728728
#> None
729729

730730
for step in run.history: # (6)!
@@ -738,7 +738,7 @@ async def main():
738738
2. The agent run is finished once an `End` node has been produced; instances of `End` cannot be passed to `next`.
739739
3. If the user decides to stop early, we break out of the loop. The graph run won't have a real final result in that case (`run.final_result` remains `None`).
740740
4. At each step, we call `await run.next(node)` to run it and get the next node (or an `End`).
741-
5. Because the run was ended early, we have no final result:
741+
5. Because we did not continue the run until it finished, the `result` is not set.
742742
6. The run's history is still populated with the steps we executed so far.
743743

744744
## Dependency Injection
@@ -798,11 +798,11 @@ fives_graph = Graph(nodes=[DivisibleBy5, Increment])
798798
async def main():
799799
with ProcessPoolExecutor() as executor:
800800
deps = GraphDeps(executor)
801-
graph_run = await fives_graph.run(DivisibleBy5(3), deps=deps)
802-
print(graph_run.result)
801+
result = await fives_graph.run(DivisibleBy5(3), deps=deps)
802+
print(result.output)
803803
#> 5
804804
# the full history is quite verbose (see below), so we'll just print the summary
805-
print([item.data_snapshot() for item in graph_run.history])
805+
print([item.data_snapshot() for item in result.history])
806806
"""
807807
[
808808
DivisibleBy5(foo=3),

Diff for: pydantic_ai_slim/pydantic_ai/agent.py

+37-52
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from typing_extensions import TypeVar, deprecated
1414

1515
from pydantic_graph import BaseNode, End, Graph, GraphRun, GraphRunContext
16-
from pydantic_graph.graph import GraphRunResult
1716

1817
from . import (
1918
_agent_graph,
@@ -215,7 +214,7 @@ async def run(
215214
usage_limits: _usage.UsageLimits | None = None,
216215
usage: _usage.Usage | None = None,
217216
infer_name: bool = True,
218-
) -> AgentRunResult[AgentDepsT, ResultDataT]: ...
217+
) -> AgentRunResult[ResultDataT]: ...
219218

220219
@overload
221220
async def run(
@@ -230,7 +229,7 @@ async def run(
230229
usage_limits: _usage.UsageLimits | None = None,
231230
usage: _usage.Usage | None = None,
232231
infer_name: bool = True,
233-
) -> AgentRunResult[AgentDepsT, RunResultDataT]: ...
232+
) -> AgentRunResult[RunResultDataT]: ...
234233

235234
async def run(
236235
self,
@@ -244,7 +243,7 @@ async def run(
244243
usage_limits: _usage.UsageLimits | None = None,
245244
usage: _usage.Usage | None = None,
246245
infer_name: bool = True,
247-
) -> AgentRunResult[AgentDepsT, Any]:
246+
) -> AgentRunResult[Any]:
248247
"""Run the agent with a user prompt in async mode.
249248
250249
This method builds an internal agent graph (using system prompts, tools and result schemas) and then
@@ -291,8 +290,8 @@ async def main():
291290
) as agent_run:
292291
async for _ in agent_run:
293292
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'
296295
return final_result
297296

298297
@contextmanager
@@ -358,7 +357,7 @@ async def main():
358357
End(data=FinalResult(data='Paris', tool_name=None)),
359358
]
360359
'''
361-
print(agent_run.final_result.data)
360+
print(agent_run.result.data)
362361
#> Paris
363362
```
364363
@@ -460,7 +459,7 @@ def run_sync(
460459
usage_limits: _usage.UsageLimits | None = None,
461460
usage: _usage.Usage | None = None,
462461
infer_name: bool = True,
463-
) -> AgentRunResult[AgentDepsT, ResultDataT]: ...
462+
) -> AgentRunResult[ResultDataT]: ...
464463

465464
@overload
466465
def run_sync(
@@ -475,7 +474,7 @@ def run_sync(
475474
usage_limits: _usage.UsageLimits | None = None,
476475
usage: _usage.Usage | None = None,
477476
infer_name: bool = True,
478-
) -> AgentRunResult[AgentDepsT, RunResultDataT]: ...
477+
) -> AgentRunResult[RunResultDataT]: ...
479478

480479
def run_sync(
481480
self,
@@ -489,7 +488,7 @@ def run_sync(
489488
usage_limits: _usage.UsageLimits | None = None,
490489
usage: _usage.Usage | None = None,
491490
infer_name: bool = True,
492-
) -> AgentRunResult[AgentDepsT, Any]:
491+
) -> AgentRunResult[Any]:
493492
"""Synchronously run the agent with a user prompt.
494493
495494
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]):
11661165
You generally obtain an `AgentRun` instance by calling `with my_agent.iter(...) as agent_run:`.
11671166
11681167
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.
11711170
11721171
Example:
11731172
```python
@@ -1207,7 +1206,7 @@ async def main():
12071206
End(data=FinalResult(data='Paris', tool_name=None)),
12081207
]
12091208
'''
1210-
print(agent_run.final_result.data)
1209+
print(agent_run.result.data)
12111210
#> Paris
12121211
```
12131212
@@ -1240,16 +1239,21 @@ def next_node(
12401239
return self._graph_run.next_node
12411240

12421241
@property
1243-
def final_result(self) -> AgentRunResult[AgentDepsT, ResultDataT] | None:
1242+
def result(self) -> AgentRunResult[ResultDataT] | None:
12441243
"""The final result of the run if it has ended, otherwise `None`.
12451244
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
12471246
with an [`AgentRunResult`][pydantic_ai.agent.AgentRunResult].
12481247
"""
1249-
graph_run_result = self._graph_run.final_result
1248+
graph_run_result = self._graph_run.result
12501249
if graph_run_result is None:
12511250
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+
)
12531257

12541258
def __aiter__(
12551259
self,
@@ -1345,7 +1349,7 @@ async def main():
13451349
End(data=FinalResult(data='Paris', tool_name=None)),
13461350
]
13471351
'''
1348-
print('Final result:', agent_run.final_result.data)
1352+
print('Final result:', agent_run.result.data)
13491353
#> Final result: Paris
13501354
```
13511355
@@ -1364,47 +1368,36 @@ def usage(self) -> _usage.Usage:
13641368
"""Get usage statistics for the run so far, including token usage, model requests, and so on."""
13651369
return self._graph_run.state.usage
13661370

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()}>'
13721375

13731376

13741377
@dataclasses.dataclass
1375-
class AgentRunResult(Generic[AgentDepsT, ResultDataT]):
1378+
class AgentRunResult(Generic[ResultDataT]):
13761379
"""The final result of an agent run."""
13771380

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
13891382

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)
13931386

13941387
def _set_result_tool_return(self, return_content: str) -> list[_messages.ModelMessage]:
13951388
"""Set return content for the result tool.
13961389
13971390
Useful if you want to continue the conversation and want to set the response to the result tool call.
13981391
"""
1399-
if not self._result.tool_name:
1392+
if not self._result_tool_name:
14001393
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)
14021395
last_message = messages[-1]
14031396
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:
14051398
part.content = return_content
14061399
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}.')
14081401

14091402
def all_messages(self, *, result_tool_return_content: str | None = None) -> list[_messages.ModelMessage]:
14101403
"""Return the history of _messages.
@@ -1421,7 +1414,7 @@ def all_messages(self, *, result_tool_return_content: str | None = None) -> list
14211414
if result_tool_return_content is not None:
14221415
return self._set_result_tool_return(result_tool_return_content)
14231416
else:
1424-
return self._graph_run_result.state.message_history
1417+
return self._state.message_history
14251418

14261419
def all_messages_json(self, *, result_tool_return_content: str | None = None) -> bytes:
14271420
"""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) ->
14391432
self.all_messages(result_tool_return_content=result_tool_return_content)
14401433
)
14411434

1442-
@property
1443-
def _new_message_index(self) -> int:
1444-
return self._graph_run_result.deps.new_message_index
1445-
14461435
def new_messages(self, *, result_tool_return_content: str | None = None) -> list[_messages.ModelMessage]:
14471436
"""Return new messages associated with this run.
14481437
@@ -1477,8 +1466,4 @@ def new_messages_json(self, *, result_tool_return_content: str | None = None) ->
14771466

14781467
def usage(self) -> _usage.Usage:
14791468
"""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

Diff for: pydantic_graph/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ class Increment(BaseNode):
5050

5151

5252
fives_graph = Graph(nodes=[DivisibleBy5, Increment])
53-
graph_run = fives_graph.run_sync(DivisibleBy5(4))
54-
print(graph_run.result)
53+
result = fives_graph.run_sync(DivisibleBy5(4))
54+
print(result.output)
5555
#> 5
5656
# the full history is quite verbose (see below), so we'll just print the summary
57-
print([item.data_snapshot() for item in graph_run.history])
57+
print([item.data_snapshot() for item in result.history])
5858
#> [DivisibleBy5(foo=4), Increment(foo=4), DivisibleBy5(foo=5), End(data=5)]
5959
```

Diff for: pydantic_graph/pydantic_graph/graph.py

+13-10
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ async def run(
134134
deps: DepsT = None,
135135
infer_name: bool = True,
136136
span: LogfireSpan | None = None,
137-
) -> GraphRunResult[StateT, DepsT, T]:
137+
) -> GraphRunResult[StateT, T]:
138138
"""Run the graph from a starting node until it ends.
139139
140140
Args:
@@ -177,7 +177,7 @@ async def main():
177177
async for _node in graph_run:
178178
pass
179179

180-
final_result = graph_run.final_result
180+
final_result = graph_run.result
181181
assert final_result is not None, 'GraphRun should have a final result'
182182
return final_result
183183

@@ -242,7 +242,7 @@ def run_sync(
242242
state: StateT = None,
243243
deps: DepsT = None,
244244
infer_name: bool = True,
245-
) -> GraphRunResult[StateT, DepsT, T]:
245+
) -> GraphRunResult[StateT, T]:
246246
"""Synchronously run the graph.
247247
248248
This is a convenience method that wraps [`self.run`][pydantic_graph.Graph.run] with `loop.run_until_complete(...)`.
@@ -659,12 +659,14 @@ def next_node(self) -> BaseNode[StateT, DepsT, RunEndT] | End[RunEndT]:
659659
return self._next_node
660660

661661
@property
662-
def final_result(self) -> GraphRunResult[StateT, DepsT, RunEndT] | None:
662+
def result(self) -> GraphRunResult[StateT, RunEndT] | None:
663663
"""The final result of the graph run if the run is completed, otherwise `None`."""
664664
if not isinstance(self._next_node, End):
665665
return None # The GraphRun has not finished running
666666
return GraphRunResult(
667-
self._next_node.data, graph=self.graph, history=self.history, state=self.state, deps=self.deps
667+
self._next_node.data,
668+
state=self.state,
669+
history=self.history,
668670
)
669671

670672
async def next(
@@ -735,13 +737,14 @@ async def __anext__(self) -> BaseNode[StateT, DepsT, RunEndT] | End[RunEndT]:
735737
raise StopAsyncIteration
736738
return await self.next(self._next_node)
737739

740+
def __repr__(self) -> str:
741+
return f'<GraphRun name={self.graph.name or "<unnamed>"} step={len(self.history) + 1}>'
742+
738743

739744
@dataclass
740-
class GraphRunResult(Generic[StateT, DepsT, RunEndT]):
745+
class GraphRunResult(Generic[StateT, RunEndT]):
741746
"""The final result of running a graph."""
742747

743-
result: RunEndT
744-
graph: Graph[StateT, DepsT, RunEndT] = field(repr=False)
745-
history: list[HistoryStep[StateT, RunEndT]]
748+
output: RunEndT
746749
state: StateT
747-
deps: DepsT
750+
history: list[HistoryStep[StateT, RunEndT]] = field(repr=False)

0 commit comments

Comments
 (0)