Python: Add declarative workflow runtime (#2815)

* Further support for declarative python workflows

* Add tests. Clean up for typing and formatting

* Improvements and cleanup

* Typing cleanup. Improve docstrings

* Proper code in docstrings

* Fix malformed code-block directive in docstring

* Remove dead links

* PR feedback

* Address PR feedback

* Address PR feedback

* Remove sl

* Update devui frontend

* More cleanup

* Fix uv lock

* Skip Py 3.14 tests as powerfx doesn't support it

* Fix mypy error

* Fix for tool calls

* Removed stale docstring

* Fix lint

* Standardize on .NET namespaces. Revert DevUI changes (bring in later)

* Implement remaining items for Python declarative support to match dotnet
This commit is contained in:
Evan Mattson
2026-01-13 16:11:21 +09:00
committed by GitHub
Unverified
parent b2893fbc00
commit 9c094573e8
79 changed files with 18310 additions and 111 deletions
@@ -839,6 +839,16 @@ class TestEnvironmentVariable:
assert env_var.value == "secret123"
# Check if PowerFx is available
try:
from powerfx import Engine as _PfxEngine
_PfxEngine()
_powerfx_available = True
except (ImportError, RuntimeError):
_powerfx_available = False
class TestTryPowerfxEval:
"""Tests for _try_powerfx_eval function."""
@@ -856,6 +866,7 @@ class TestTryPowerfxEval:
"""Test that empty strings are returned as empty."""
assert _try_powerfx_eval("") == ""
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_simple_powerfx_expressions(self):
"""Test simple PowerFx expressions."""
from decimal import Decimal
@@ -868,6 +879,7 @@ class TestTryPowerfxEval:
assert _try_powerfx_eval('="hello"') == "hello"
assert _try_powerfx_eval('="test value"') == "test value"
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_env_variable_access(self, monkeypatch):
"""Test accessing environment variables using =Env.<name> pattern."""
# Set up test environment variables
@@ -885,6 +897,7 @@ class TestTryPowerfxEval:
finally:
_safe_mode_context.reset(token)
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_env_variable_with_string_concatenation(self, monkeypatch):
"""Test env variables with string concatenation operator."""
monkeypatch.setenv("BASE_URL", "https://api.example.com")
@@ -903,6 +916,7 @@ class TestTryPowerfxEval:
finally:
_safe_mode_context.reset(token)
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_string_comparison_operators(self, monkeypatch):
"""Test PowerFx string comparison operators."""
monkeypatch.setenv("ENV_MODE", "production")
@@ -920,6 +934,7 @@ class TestTryPowerfxEval:
finally:
_safe_mode_context.reset(token)
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_string_in_operator(self):
"""Test PowerFx 'in' operator for substring testing (case-insensitive)."""
# Substring test - case insensitive - returns bool
@@ -927,6 +942,7 @@ class TestTryPowerfxEval:
assert _try_powerfx_eval('="THE" in "The keyboard and the monitor"') is True
assert _try_powerfx_eval('="xyz" in "The keyboard and the monitor"') is False
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_string_exactin_operator(self):
"""Test PowerFx 'exactin' operator for substring testing (case-sensitive)."""
# Substring test - case sensitive - returns bool
@@ -934,6 +950,7 @@ class TestTryPowerfxEval:
assert _try_powerfx_eval('="windows" exactin "To display windows in the Windows operating system"') is True
assert _try_powerfx_eval('="WINDOWS" exactin "To display windows in the Windows operating system"') is False
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_logical_operators_with_strings(self):
"""Test PowerFx logical operators (And, Or, Not) with string comparisons."""
# And operator - returns bool
@@ -957,6 +974,7 @@ class TestTryPowerfxEval:
# ! operator (alternative syntax) - returns bool
assert _try_powerfx_eval('=!("a" = "b")') is True
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_parentheses_for_precedence(self):
"""Test using parentheses to control operator precedence."""
from decimal import Decimal
@@ -969,6 +987,7 @@ class TestTryPowerfxEval:
result = _try_powerfx_eval('=("a" = "a" Or "b" = "c") And "d" = "d"')
assert result is True
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_env_with_special_characters(self, monkeypatch):
"""Test env variables containing special characters in values."""
monkeypatch.setenv("URL_WITH_QUERY", "https://example.com?param=value")
@@ -999,6 +1018,7 @@ class TestTryPowerfxEval:
finally:
_safe_mode_context.reset(token)
@pytest.mark.skipif(not _powerfx_available, reason="PowerFx engine not available")
def test_safe_mode_context_isolation(self, monkeypatch):
"""Test that safe_mode context variable properly isolates env access."""
monkeypatch.setenv("TEST_VAR", "test_value")