Skip to content

Commit 86b645f

Browse files
tibbeDouweM
andauthored
Add AgentRun.{all,new}_messages{_json} (#3354)
Co-authored-by: Douwe Maan <[email protected]>
1 parent f666597 commit 86b645f

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

pydantic_ai_slim/pydantic_ai/run.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,36 @@ def result(self) -> AgentRunResult[OutputDataT] | None:
135135
self._traceparent(required=False),
136136
)
137137

138+
def all_messages(self) -> list[_messages.ModelMessage]:
139+
"""Return all messages for the run so far.
140+
141+
Messages from older runs are included.
142+
"""
143+
return self.ctx.state.message_history
144+
145+
def all_messages_json(self, *, output_tool_return_content: str | None = None) -> bytes:
146+
"""Return all messages from [`all_messages`][pydantic_ai.agent.AgentRun.all_messages] as JSON bytes.
147+
148+
Returns:
149+
JSON bytes representing the messages.
150+
"""
151+
return _messages.ModelMessagesTypeAdapter.dump_json(self.all_messages())
152+
153+
def new_messages(self) -> list[_messages.ModelMessage]:
154+
"""Return new messages for the run so far.
155+
156+
Messages from older runs are excluded.
157+
"""
158+
return self.all_messages()[self.ctx.deps.new_message_index :]
159+
160+
def new_messages_json(self) -> bytes:
161+
"""Return new messages from [`new_messages`][pydantic_ai.agent.AgentRun.new_messages] as JSON bytes.
162+
163+
Returns:
164+
JSON bytes representing the new messages.
165+
"""
166+
return _messages.ModelMessagesTypeAdapter.dump_json(self.new_messages())
167+
138168
def __aiter__(
139169
self,
140170
) -> AsyncIterator[_agent_graph.AgentNode[AgentDepsT, OutputDataT] | End[FinalResult[OutputDataT]]]:

tests/test_agent.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5833,3 +5833,48 @@ def delete_file() -> None:
58335833
assert result.output == snapshot(
58345834
DeferredToolRequests(approvals=[ToolCallPart(tool_name='delete_file', tool_call_id=IsStr())])
58355835
)
5836+
5837+
5838+
async def test_message_history():
5839+
def llm(messages: list[ModelMessage], _info: AgentInfo) -> ModelResponse:
5840+
return ModelResponse(parts=[TextPart('ok here is text')])
5841+
5842+
agent = Agent(FunctionModel(llm))
5843+
5844+
async with agent.iter(
5845+
message_history=[
5846+
ModelRequest(parts=[UserPromptPart(content='Hello')]),
5847+
],
5848+
) as run:
5849+
async for _ in run:
5850+
pass
5851+
assert run.new_messages() == snapshot(
5852+
[
5853+
ModelResponse(
5854+
parts=[TextPart(content='ok here is text')],
5855+
usage=RequestUsage(input_tokens=51, output_tokens=4),
5856+
model_name='function:llm:',
5857+
timestamp=IsDatetime(),
5858+
),
5859+
]
5860+
)
5861+
assert run.new_messages_json().startswith(b'[{"parts":[{"content":"ok here is text",')
5862+
assert run.all_messages() == snapshot(
5863+
[
5864+
ModelRequest(
5865+
parts=[
5866+
UserPromptPart(
5867+
content='Hello',
5868+
timestamp=IsDatetime(),
5869+
)
5870+
]
5871+
),
5872+
ModelResponse(
5873+
parts=[TextPart(content='ok here is text')],
5874+
usage=RequestUsage(input_tokens=51, output_tokens=4),
5875+
model_name='function:llm:',
5876+
timestamp=IsDatetime(),
5877+
),
5878+
]
5879+
)
5880+
assert run.all_messages_json().startswith(b'[{"parts":[{"content":"Hello",')

0 commit comments

Comments
 (0)