From c37afab1ff9449a7e6b9c62f8b0c8130394e2ca7 Mon Sep 17 00:00:00 2001 From: Greyson LaLonde Date: Thu, 21 May 2026 01:06:24 +0800 Subject: [PATCH] fix: snapshot RecordingPersistence state and guard isclass formatting --- lib/crewai/src/crewai/types/callback.py | 6 ++++-- lib/crewai/tests/test_flow_ask.py | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/crewai/src/crewai/types/callback.py b/lib/crewai/src/crewai/types/callback.py index d4ec14b5a..119d7d517 100644 --- a/lib/crewai/src/crewai/types/callback.py +++ b/lib/crewai/src/crewai/types/callback.py @@ -155,9 +155,11 @@ SerializableCallable = Annotated[ def _instance_to_dotted_path(value: Any) -> str: """Serialize an instance to a dotted path naming its class.""" if inspect.isclass(value): - raise ValueError( - f"Expected an instance, got class {value.__module__}.{value.__qualname__}." + module = getattr(value, "__module__", "") + qualname = getattr( + value, "__qualname__", getattr(value, "__name__", str(type(value))) ) + raise ValueError(f"Expected an instance, got class {module}.{qualname}.") cls = type(value) if cls.__module__ == "builtins": raise ValueError( diff --git a/lib/crewai/tests/test_flow_ask.py b/lib/crewai/tests/test_flow_ask.py index ed616d1be..5ba3729df 100644 --- a/lib/crewai/tests/test_flow_ask.py +++ b/lib/crewai/tests/test_flow_ask.py @@ -7,6 +7,7 @@ durability, input history tracking, and integration with flow machinery. from __future__ import annotations +import copy import time from datetime import datetime from typing import Any @@ -47,10 +48,15 @@ class _SaveStateRecorder: method_name: str, state_data: dict[str, Any] | BaseModel, ) -> None: + snapshot: dict[str, Any] | BaseModel + if isinstance(state_data, BaseModel): + snapshot = state_data.model_copy(deep=True) + else: + snapshot = copy.deepcopy(state_data) self.call_args_list.append( - _SaveCall((flow_uuid, method_name, state_data), {}) + _SaveCall((flow_uuid, method_name, snapshot), {}) ) - self._owner._states[flow_uuid] = state_data + self._owner._states[flow_uuid] = snapshot class RecordingPersistence(FlowPersistence): @@ -74,7 +80,12 @@ class RecordingPersistence(FlowPersistence): return None def load_state(self, flow_uuid: str) -> dict[str, Any] | None: - return None + snapshot = self._states.get(flow_uuid) + if snapshot is None: + return None + if isinstance(snapshot, BaseModel): + return snapshot.model_copy(deep=True).model_dump() + return copy.deepcopy(snapshot) class MockInputProvider: