From c6588e359e2a15361e54799cde06b0babc05ce00 Mon Sep 17 00:00:00 2001 From: Somay-kousis Date: Thu, 15 Oct 2026 22:31:26 +0530 Subject: [PATCH 1/4] Python: test that declarative SetValue writes to its variable field --- .../declarative/tests/test_graph_coverage.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/python/packages/declarative/tests/test_graph_coverage.py b/python/packages/declarative/tests/test_graph_coverage.py index 5b150bf497f..d0b80fb1891 100644 --- a/python/packages/declarative/tests/test_graph_coverage.py +++ b/python/packages/declarative/tests/test_graph_coverage.py @@ -451,6 +451,20 @@ async def test_set_variable_executor(self, mock_context, mock_state): result = state.get("Local.result") assert result == "test value" + @pytest.mark.parametrize("variable", ["Local.target", {"path": "Local.target"}]) + async def test_set_value_executor_with_variable_field(self, mock_context, mock_state, variable): + """SetValue accepts 'variable' in place of 'path', so it must write to it.""" + from agent_framework_declarative._workflows._executors_basic import SetValueExecutor + + state = DeclarativeWorkflowState(mock_state) + state.initialize() + + action_def = {"kind": "SetValue", "variable": variable, "value": "test value"} + executor = SetValueExecutor(action_def) + await executor.handle_action(ActionTrigger(), mock_context) + + assert state.get("Local.target") == "test value" + async def test_set_variable_executor_with_nested_variable(self, mock_context, mock_state): """Test SetVariableExecutor with nested variable object.""" from agent_framework_declarative._workflows._executors_basic import ( From 12de5bc3a7508ac94a0a93d95439e31422c8ae61 Mon Sep 17 00:00:00 2001 From: Somay-kousis Date: Thu, 15 Oct 2026 22:31:30 +0530 Subject: [PATCH 2/4] Python: fix(declarative): honor the variable field in SetValue --- .../agent_framework_declarative/_workflows/_executors_basic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/packages/declarative/agent_framework_declarative/_workflows/_executors_basic.py b/python/packages/declarative/agent_framework_declarative/_workflows/_executors_basic.py index 34153b242a5..76b264488c8 100644 --- a/python/packages/declarative/agent_framework_declarative/_workflows/_executors_basic.py +++ b/python/packages/declarative/agent_framework_declarative/_workflows/_executors_basic.py @@ -53,7 +53,8 @@ async def handle_action( """Handle the SetValue action.""" state = await self._ensure_state_initialized(ctx, trigger) - path = self._action_def.get("path") + # The builder accepts 'variable' in place of 'path' for SetValue + path = self._action_def.get("path") or _get_variable_path(self._action_def) value = self._action_def.get("value") if path: From 8cdf12d62ca3b8342a469b29af027906fe66acee Mon Sep 17 00:00:00 2001 From: Somay-kousis Date: Thu, 15 Oct 2026 22:35:57 +0530 Subject: [PATCH 3/4] Python: test that SetValue path wins over variable --- .../declarative/tests/test_graph_coverage.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/python/packages/declarative/tests/test_graph_coverage.py b/python/packages/declarative/tests/test_graph_coverage.py index d0b80fb1891..7187b317f8c 100644 --- a/python/packages/declarative/tests/test_graph_coverage.py +++ b/python/packages/declarative/tests/test_graph_coverage.py @@ -465,6 +465,20 @@ async def test_set_value_executor_with_variable_field(self, mock_context, mock_s assert state.get("Local.target") == "test value" + async def test_set_value_executor_path_wins_over_variable(self, mock_context, mock_state): + """When SetValue has both 'path' and 'variable', 'path' is used.""" + from agent_framework_declarative._workflows._executors_basic import SetValueExecutor + + state = DeclarativeWorkflowState(mock_state) + state.initialize() + + action_def = {"kind": "SetValue", "path": "Local.a", "variable": "Local.b", "value": "v"} + executor = SetValueExecutor(action_def) + await executor.handle_action(ActionTrigger(), mock_context) + + assert state.get("Local.a") == "v" + assert state.get("Local.b") is None + async def test_set_variable_executor_with_nested_variable(self, mock_context, mock_state): """Test SetVariableExecutor with nested variable object.""" from agent_framework_declarative._workflows._executors_basic import ( From 8d8053c8061981e81beb0ec6f35cf9afe3fbd6b5 Mon Sep 17 00:00:00 2001 From: Somay-kousis Date: Thu, 15 Oct 2026 23:18:00 +0530 Subject: [PATCH 4/4] Python: test SetValue variable alias through a real factory run --- .../tests/test_workflow_factory.py | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/python/packages/declarative/tests/test_workflow_factory.py b/python/packages/declarative/tests/test_workflow_factory.py index 034782a2968..46b3d11a9e1 100644 --- a/python/packages/declarative/tests/test_workflow_factory.py +++ b/python/packages/declarative/tests/test_workflow_factory.py @@ -359,6 +359,39 @@ async def test_devui_declarative_workflow_categorizes_message_input(self, age: i assert any(f"categorized as: {category}" in str(output) for output in outputs) +class TestWorkflowFactorySetValueAlias: + """SetValue's 'variable' alias through a real factory run. Literal values, so no PowerFx needed.""" + + @pytest.mark.parametrize( + "variable_yaml", + ["variable: Local.target", "variable:\n path: Local.target"], + ids=["string", "nested"], + ) + async def test_set_value_variable_alias_persists_in_checkpoint(self, variable_yaml: str) -> None: + """The builder accepts 'variable' for SetValue, so a real run must write and checkpoint it.""" + from agent_framework import InMemoryCheckpointStorage + + from agent_framework_declarative._workflows._declarative_base import DECLARATIVE_STATE_KEY + + storage = InMemoryCheckpointStorage() + workflow = WorkflowFactory(checkpoint_storage=storage).create_workflow_from_yaml(f""" +name: set-value-variable-alias +actions: + - kind: SetValue + {variable_yaml} + value: from variable +""") + await workflow.run({}) + + checkpoints = await storage.list_checkpoints(workflow_name=workflow.name) + assert checkpoints + # Early checkpoints are taken before the declarative state exists. + saved = [ + checkpoint.state.get(DECLARATIVE_STATE_KEY, {}).get("Local", {}).get("target") for checkpoint in checkpoints + ] + assert "from variable" in saved + + @_requires_powerfx class TestWorkflowFactoryExecution: """Tests for workflow execution."""