-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Description
Hello, we face and issue with durable function and declarative workflows.
We found that when an activity like "parse_code_1" updates a state value (e.g., Local.code), downstream activities never receive the updated value — it's always blank. This caused "evaluate_1" to always evaluate Not(IsBlank(Local.code)) as False.
- kind: ParseCode
id: parse_code_1
description: >
Parses code and sets in workflow context.
- kind: If
id: evaluate_1
description: >
Gate: only proceed if code parsed.
condition: "=Not(IsBlank(Local.code))"
We traced this to _app.py in the agent framework, where the activity executor snapshots the workflow state before execution using dict(). Since dict() only creates a shallow copy, nested state objects are still shared references. When the activity mutates a nested value in place, the snapshot is silently modified too, making the before/after diff empty — so no changes are propagated forward.
about line 300...
# Deserialize shared state values to reconstruct dataclasses/Pydantic models
deserialized_state = {k: deserialize_value(v) for k, v in (shared_state_snapshot or {}).items()}
original_snapshot = dict(deserialized_state)
In our testing, replacing the shallow copy with copy.deepcopy() resolved the issue. However, we'd like the framework owners to review and determine the appropriate fix, as there may be broader implications we're not aware of.
# Deserialize shared state values to reconstruct dataclasses/Pydantic models
deserialized_state = {k: deserialize_value(v) for k, v in (shared_state_snapshot or {}).items()}
original_snapshot = copy.deepcopy(deserialized_state)
Thank you for having look into it!
Code Sample
Following code is working with fix described above.
ParseCodeExecutor(DeclarativeActionExecutor):
...
state.set("Local.code", "SOMECODEXXX")
code_check = state.get("Local.code")
logger.warning("[ParseCode] STATE-DEBUG: Local.code after set = %r", code_check)
CodeReaderExecutor(DeclarativeActionExecutor):
...
code_check = state.get("Local.code")
logger.warning("[CodeReader] STATE-DEBUG: Local.code after set = %r", code_check)Error Messages / Stack Traces
Package Versions
agent-framework-azurefunctions>=1.0.0b260225; agent-framework-declarative>=1.0.0b260225;agent-framework-durabletask>=1.0.0b260225
Python Version
Python 3.12
Additional Context
No response