From f8e5ffa5958cc7f20d0c6d2a5684b6edbe9961dc Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Thu, 11 Jun 2026 13:28:59 -0700 Subject: [PATCH] Make cached_result and replay serialized replay/cached_result shouldn't appear in the output messages from a stream, so won't get serialized durably by apps in normal cases anyway, but this lets us insert a JSON serialization between loop and stream for workflows, etc. --- src/ai/types/messages.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ai/types/messages.py b/src/ai/types/messages.py index 78887b4..ffaa150 100644 --- a/src/ai/types/messages.py +++ b/src/ai/types/messages.py @@ -242,10 +242,11 @@ class ToolCallPart(pydantic.BaseModel): # run completed this tool call but a sibling tool call was suspended # on a hook, we fold the completed result onto the ``ToolCallPart`` # so re-execution short-circuits to the cached value instead of - # running the tool body again. Excluded from JSON; not part of the - # wire model. + # running the tool body again. cached_result: ToolResultPart | None = pydantic.Field( - default=None, exclude=True, repr=False + default=None, + exclude_if=lambda v: v is None, + repr=False, ) kind: Literal["tool_call"] = "tool_call" @@ -331,9 +332,12 @@ class Message(pydantic.BaseModel): # short-circuiting an existing assistant turn (resume-after-approval # flows). ``Context.add`` skips replay-flagged messages so the loop # can call ``context.add(stream.message)`` unconditionally without - # producing a duplicate turn. Excluded from JSON: control flag, - # not data. - replay: bool = pydantic.Field(default=False, exclude=True, repr=False) + # producing a duplicate turn. + replay: bool = pydantic.Field( + default=False, + exclude_if=lambda v: not v, + repr=False, + ) @property def text(self) -> str: