[BREAKING] Python: Merge send_responses into run method (#3720)

* Streamline workflow run api with send responses in one method

* Fixes

* Address copilot feedback
This commit is contained in:
Evan Mattson
2026-02-06 22:32:38 +00:00
committed by GitHub
parent 15256bb616
commit a17f13598b
39 changed files with 561 additions and 335 deletions
@@ -1524,7 +1524,7 @@ class MagenticBuilder:
if request.kind == MagenticHumanInterventionKind.PLAN_REVIEW:
# Review plan and respond
reply = MagenticHumanInterventionReply(decision=MagenticHumanInterventionDecision.APPROVE)
await workflow.send_responses({event.request_id: reply})
await workflow.run(responses={event.request_id: reply})
See Also:
- :class:`MagenticHumanInterventionRequest`: Event emitted for review
@@ -784,9 +784,9 @@ async def test_group_chat_with_request_info_filtering():
# Continue the workflow with a response
outputs: list[WorkflowEvent] = []
async for event in workflow.send_responses_streaming({
request_event.request_id: AgentRequestInfoResponse.approve()
}):
async for event in workflow.run(
stream=True, responses={request_event.request_id: AgentRequestInfoResponse.approve()}
):
if event.type == "output":
outputs.append(event)
@@ -255,9 +255,9 @@ async def test_handoff_async_termination_condition() -> None:
assert requests
events = await _drain(
workflow.send_responses_streaming({
requests[-1].request_id: [ChatMessage(role="user", text="Second user message")]
})
workflow.run(
stream=True, responses={requests[-1].request_id: [ChatMessage(role="user", text="Second user message")]}
)
)
outputs = [ev for ev in events if ev.type == "output"]
assert len(outputs) == 1
@@ -508,7 +508,7 @@ async def test_handoff_with_participant_factories():
# Follow-up message
events = await _drain(
workflow.send_responses_streaming({requests[-1].request_id: [ChatMessage(role="user", text="More details")]})
workflow.run(stream=True, responses={requests[-1].request_id: [ChatMessage(role="user", text="More details")]})
)
outputs = [ev for ev in events if ev.type == "output"]
assert outputs
@@ -582,7 +582,9 @@ async def test_handoff_with_participant_factories_and_add_handoff():
# Second user message - specialist_a hands off to specialist_b
events = await _drain(
workflow.send_responses_streaming({requests[-1].request_id: [ChatMessage(role="user", text="Need escalation")]})
workflow.run(
stream=True, responses={requests[-1].request_id: [ChatMessage(role="user", text="Need escalation")]}
)
)
requests = [ev for ev in events if ev.type == "request_info"]
assert requests
@@ -617,7 +619,7 @@ async def test_handoff_participant_factories_with_checkpointing():
assert requests
events = await _drain(
workflow.send_responses_streaming({requests[-1].request_id: [ChatMessage(role="user", text="follow up")]})
workflow.run(stream=True, responses={requests[-1].request_id: [ChatMessage(role="user", text="follow up")]})
)
outputs = [ev for ev in events if ev.type == "output"]
assert outputs, "Should have workflow output after termination condition is met"
@@ -251,7 +251,7 @@ async def test_magentic_workflow_plan_review_approval_to_completion():
completed = False
output: list[ChatMessage] | None = None
async for ev in wf.send_responses_streaming(responses={req_event.request_id: req_event.data.approve()}):
async for ev in wf.run(stream=True, responses={req_event.request_id: req_event.data.approve()}):
if ev.type == "status" and ev.state == WorkflowRunState.IDLE:
completed = True
elif ev.type == "output":
@@ -297,16 +297,17 @@ async def test_magentic_plan_review_with_revise():
# Send a revise response
saw_second_review = False
completed = False
async for ev in wf.send_responses_streaming(
responses={req_event.request_id: req_event.data.revise("Looks good; consider Z")}
async for ev in wf.run(
stream=True, responses={req_event.request_id: req_event.data.revise("Looks good; consider Z")}
):
if ev.type == "request_info" and ev.request_type is MagenticPlanReviewRequest:
saw_second_review = True
req_event = ev
# Approve the second review
async for ev in wf.send_responses_streaming(
responses={req_event.request_id: req_event.data.approve()} # type: ignore[union-attr]
async for ev in wf.run(
stream=True,
responses={req_event.request_id: req_event.data.approve()}, # type: ignore[union-attr]
):
if ev.type == "status" and ev.state == WorkflowRunState.IDLE:
completed = True
@@ -397,7 +398,7 @@ async def test_magentic_checkpoint_resume_round_trip():
assert isinstance(req_event.data, MagenticPlanReviewRequest)
responses = {req_event.request_id: req_event.data.approve()}
async for event in wf_resume.send_responses_streaming(responses=responses):
async for event in wf_resume.run(stream=True, responses=responses):
if event.type == "output":
completed = event
assert completed is not None