mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Add regression tests for Entry JoinExecutor Workflow.Inputs initialization (#4335)
* Python: Add regression tests for #3948 - Entry JoinExecutor initializes Workflow.Inputs Add tests verifying that when workflow.run() is called with a dict or string input, the Entry node (JoinExecutor with kind: 'Entry') correctly initializes Workflow.Inputs via _ensure_state_initialized so that: - Expressions like =inputs.age resolve to the correct value - Conditions like =Local.age < 13 evaluate based on actual input (not blank/0) - String inputs populate both inputs.input and System.LastMessage.Text Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply pre-commit auto-fixes * Fix D420 and RUF070 lint errors across packages * Revert _workflow.py yield-inside-context-manager changes Moving yield inside `with _framework_event_origin()` blocks in the async generator causes ContextVar token reset failures on Python 3.12 Windows. The token stays un-reset while the generator is suspended, and async generator finalization in a different contextvars.Context triggers ValueError, corrupting OpenTelemetry span state and causing test_span_creation_and_attributes to see leaked spans. Keep yields outside the context manager blocks to ensure tokens are reset immediately before the generator suspends. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
debec5208c
commit
2e9319359b
@@ -159,6 +159,75 @@ actions:
|
||||
_text_outputs = [str(o) for o in outputs if isinstance(o, str) or hasattr(o, "data")] # noqa: F841
|
||||
assert any("Condition was true" in str(o) for o in outputs)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_entry_join_executor_initializes_workflow_inputs(self):
|
||||
"""Regression test for #3948: Entry JoinExecutor must initialize Workflow.Inputs.
|
||||
|
||||
When workflow.run() is called with a dict input, the Entry node (JoinExecutor
|
||||
with kind: 'Entry') must call _ensure_state_initialized so that Workflow.Inputs
|
||||
is populated. Without this, expressions like =inputs.age resolve to blank and
|
||||
conditions like =Local.age < 13 always evaluate as true (blank treated as 0).
|
||||
"""
|
||||
factory = WorkflowFactory()
|
||||
workflow = factory.create_workflow_from_yaml("""
|
||||
name: entry-inputs-test
|
||||
actions:
|
||||
- kind: SetValue
|
||||
id: get_age
|
||||
path: Local.age
|
||||
value: =inputs.age
|
||||
- kind: If
|
||||
id: check_age
|
||||
condition: =Local.age < 13
|
||||
then:
|
||||
- kind: SendActivity
|
||||
activity:
|
||||
text: child
|
||||
else:
|
||||
- kind: SendActivity
|
||||
activity:
|
||||
text: adult
|
||||
""")
|
||||
|
||||
# age=8 -> child branch
|
||||
result_child = await workflow.run({"age": 8})
|
||||
outputs_child = result_child.get_outputs()
|
||||
assert any("child" in str(o) for o in outputs_child), f"Expected 'child' for age=8 but got: {outputs_child}"
|
||||
assert not any("adult" in str(o) for o in outputs_child), (
|
||||
f"Did not expect 'adult' for age=8 but got: {outputs_child}"
|
||||
)
|
||||
|
||||
# age=25 -> adult branch (bug: blank treated as 0 made this always go to child)
|
||||
result_adult = await workflow.run({"age": 25})
|
||||
outputs_adult = result_adult.get_outputs()
|
||||
assert any("adult" in str(o) for o in outputs_adult), f"Expected 'adult' for age=25 but got: {outputs_adult}"
|
||||
assert not any("child" in str(o) for o in outputs_adult), (
|
||||
f"Did not expect 'child' for age=25 but got: {outputs_adult}"
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_entry_join_executor_initializes_workflow_inputs_string(self):
|
||||
"""Regression test for #3948: Entry JoinExecutor must initialize Workflow.Inputs for string input.
|
||||
|
||||
When workflow.run() is called with a string input, Workflow.Inputs.input and
|
||||
System.LastMessage.Text should be set correctly.
|
||||
"""
|
||||
factory = WorkflowFactory()
|
||||
workflow = factory.create_workflow_from_yaml("""
|
||||
name: entry-string-inputs-test
|
||||
actions:
|
||||
- kind: SetValue
|
||||
path: Local.msg
|
||||
value: =inputs.input
|
||||
- kind: SendActivity
|
||||
activity:
|
||||
text: =Local.msg
|
||||
""")
|
||||
|
||||
result = await workflow.run("hello-world")
|
||||
outputs = result.get_outputs()
|
||||
assert any("hello-world" in str(o) for o in outputs), f"Expected 'hello-world' in outputs but got: {outputs}"
|
||||
|
||||
|
||||
class TestWorkflowFactoryAgentRegistration:
|
||||
"""Tests for agent registration."""
|
||||
|
||||
Reference in New Issue
Block a user