From 74a3dd2b1f1b0b79c60bde4758438be83ad62255 Mon Sep 17 00:00:00 2001 From: lda Date: Sat, 5 Sep 2026 01:40:38 +0700 Subject: [PATCH] fix: drop obsolete eval_condition context_data parameter --- src/wf_core/conditions.py | 28 ++++++++++------------------ src/wf_core/runtime/ops/handlers.py | 1 - tests/authoring/test_conditions.py | 2 +- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/wf_core/conditions.py b/src/wf_core/conditions.py index b2b26b36..abead07b 100644 --- a/src/wf_core/conditions.py +++ b/src/wf_core/conditions.py @@ -20,43 +20,36 @@ def eval_condition( condition: Condition, state: Mapping[str, Any], workflow_input: Mapping[str, Any], - context_data: str | None, *, - context: Mapping[str, Any] | None = None, + context: Mapping[str, Any], ) -> bool: """Evaluate a condition against state, input, and context. ``context`` is the frame's structured context graph (see - ``frame_context_view``); when omitted, evaluation falls back to the - legacy ``{"prior_outcome": context_data}`` stub so direct unit callers - keep working. The graph always carries ``prior_outcome``, so passing it - preserves legacy behavior while also resolving structured paths such as - ``context.foreach..item``. + ``frame_context_view``); it always carries ``prior_outcome`` alongside the + structured ``foreach`` entries, aliases, and loop keys. """ - resolved = context if context is not None else {"prior_outcome": context_data} if isinstance(condition, ExistsCondition): return path_exists( condition.path, state=state, workflow_input=workflow_input, - context=resolved, + context=context, ) if isinstance(condition, NotCondition): return not eval_condition( - condition.arg, state, workflow_input, context_data, context=resolved + condition.arg, state, workflow_input, context=context ) if isinstance(condition, VariadicCondition): values = [ - eval_condition(arg, state, workflow_input, context_data, context=resolved) + eval_condition(arg, state, workflow_input, context=context) for arg in condition.args ] return all(values) if condition.op == "and" else any(values) if isinstance(condition, BinaryCondition): - left = resolve_operand( - condition.left, state, workflow_input, context_data, context=resolved - ) + left = resolve_operand(condition.left, state, workflow_input, context=context) right = resolve_operand( - condition.right, state, workflow_input, context_data, context=resolved + condition.right, state, workflow_input, context=context ) if condition.op == "eq": return left == right @@ -77,9 +70,8 @@ def resolve_operand( operand: PathOperand | LiteralOperand, state: Mapping[str, Any], workflow_input: Mapping[str, Any], - context_data: str | None, *, - context: Mapping[str, Any] | None = None, + context: Mapping[str, Any], ) -> Any: if isinstance(operand, LiteralOperand): return operand.value @@ -87,7 +79,7 @@ def resolve_operand( str(operand.path), state=state, workflow_input=workflow_input, - context=context if context is not None else {"prior_outcome": context_data}, + context=context, ) diff --git a/src/wf_core/runtime/ops/handlers.py b/src/wf_core/runtime/ops/handlers.py index 89e9216d..31df0da9 100644 --- a/src/wf_core/runtime/ops/handlers.py +++ b/src/wf_core/runtime/ops/handlers.py @@ -28,7 +28,6 @@ def handle_condition_step( step.check, state_view_for_frame(run, frame), scope_input_for_frame(run, frame), - frame.prior_outcome, # Structured context must match what validation blesses: conditions # inside a foreach body can read context.foreach.* / loop aliases. context=frame_context_view(run, frame).graph, diff --git a/tests/authoring/test_conditions.py b/tests/authoring/test_conditions.py index 14219dac..f2e339a3 100644 --- a/tests/authoring/test_conditions.py +++ b/tests/authoring/test_conditions.py @@ -45,5 +45,5 @@ def test_condition_dsl_supports_not_ge_and_ne() -> None: compiled, state={"score": 7, "status": "ready"}, workflow_input={}, - context_data=None, + context={"prior_outcome": None}, )