From 1d28f974b34cd103541d81dd9d13f5df1000384f Mon Sep 17 00:00:00 2001 From: Henry Su Date: Wed, 29 Jul 2026 00:07:07 -0500 Subject: [PATCH] fix(python): preserve falsey EditTableV2 items --- .../_workflows/_executors_basic.py | 4 +- .../declarative/tests/test_graph_executors.py | 43 +++++++++++++++++++ 2 files changed, 46 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 d876c2c45ef..7ce1d0f0899 100644 --- a/python/packages/declarative/agent_framework_declarative/_workflows/_executors_basic.py +++ b/python/packages/declarative/agent_framework_declarative/_workflows/_executors_basic.py @@ -361,7 +361,9 @@ async def handle_action( table_path = self._action_def.get("table") or _get_variable_path(self._action_def, "variable") operation = self._action_def.get("operation", "add").lower() - item = self._action_def.get("item") or self._action_def.get("value") + item = self._action_def.get("item") + if item is None: + item = self._action_def.get("value") key_field = self._action_def.get("key") index = self._action_def.get("index") diff --git a/python/packages/declarative/tests/test_graph_executors.py b/python/packages/declarative/tests/test_graph_executors.py index 885d3457c9f..5dce56d4e7b 100644 --- a/python/packages/declarative/tests/test_graph_executors.py +++ b/python/packages/declarative/tests/test_graph_executors.py @@ -934,6 +934,49 @@ async def test_edit_table_v2_add(self, mock_context, mock_state): result = state.get("Local.records") assert result == [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}] + @pytest.mark.parametrize("item", [False, 0, "", [], {}]) + async def test_edit_table_v2_add_preserves_falsey_item(self, mock_context, mock_state, item): + """Test EditTableV2 preserves a falsey item instead of treating it as missing.""" + from agent_framework_declarative._workflows._executors_basic import EditTableV2Executor + + state = DeclarativeWorkflowState(mock_state) + state.initialize() + state.set("Local.items", [True]) + + action_def = { + "kind": "EditTableV2", + "table": "Local.items", + "operation": "add", + "item": item, + } + executor = EditTableV2Executor(action_def) + await executor.handle_action(ActionTrigger(), mock_context) + + result = state.get("Local.items") + assert result[:-1] == [True] + assert result[-1] == item + assert type(result[-1]) is type(item) + + async def test_edit_table_v2_add_uses_legacy_value_when_item_is_none(self, mock_context, mock_state): + """Test EditTableV2 retains the legacy value fallback for a missing item.""" + from agent_framework_declarative._workflows._executors_basic import EditTableV2Executor + + state = DeclarativeWorkflowState(mock_state) + state.initialize() + + action_def = { + "kind": "EditTableV2", + "table": "Local.items", + "operation": "add", + "item": None, + "value": "legacy", + } + executor = EditTableV2Executor(action_def) + await executor.handle_action(ActionTrigger(), mock_context) + + result = state.get("Local.items") + assert result == ["legacy"] + @pytest.mark.asyncio async def test_edit_table_v2_add_or_update_new(self, mock_context, mock_state): """Test EditTableV2 with addOrUpdate - adding new record."""