Context
PR #5623 (merged 2026-05-19) reshapes how workflows and orchestrations distinguish terminal answers from observational/progress emissions, renames the relevant builder kwargs, and adds new accessors. The docs at microsoft/semantic-kernel (agent-framework/ path) need a refresh to match.
This issue is scoped to docs only. No code changes.
PR: #5623
Summary of what changed in code
- New event discriminator.
WorkflowEvent.type == "intermediate" joins "output" (terminal). Legacy "data" is now a deprecated alias for "intermediate".
- Build-time per-executor designation.
WorkflowBuilder(final_output_from=[...], intermediate_output_from=[...]). Designation is fixed at build time. ctx.yield_output(...) has no per-emission flag, and an executor cannot vary the label per yield.
- New accessor.
WorkflowRunResult.get_intermediate_outputs() alongside get_outputs().
workflow.as_agent() boundary. Now forwards both output and intermediate events (explicit allowlist AGENT_FORWARDED_EVENT_TYPES). Intermediates render as text_reasoning content; existing .text still returns only the terminal answer.
WorkflowExecutor (sub-workflow embedding). Child intermediate emissions now bubble up through the parent's event stream, attributed to the WorkflowExecutor's own id (preserves encapsulation), and keep the intermediate label regardless of how the parent designates the WorkflowExecutor.
- Builder kwarg renames:
- Core (
agent_framework): output_executors -> final_output_from, intermediate_executors -> intermediate_output_from. Old names still accepted with DeprecationWarning. Supplying both old and new raises TypeError. Serialized form (Workflow.to_dict()) intentionally keeps the legacy wire keys output_executors / intermediate_executors for checkpoint compat.
- Orchestrations (
agent_framework_orchestrations): output_participants -> final_output_from, intermediate_participants -> intermediate_output_from. Clean break, no shim (pre-1.0 package).
- Orchestration default-final + intermediate interaction.
HandoffBuilder defaults final_output_from to every participant; SequentialBuilder defaults to the last participant. Supplying intermediate_output_from=[X] now implicitly demotes X out of the default-final set (previously raised an overlap error).
- New canonical sample:
python/samples/03-workflows/control-flow/intermediate_vs_terminal_outputs.py walks explicit designation, streaming consumption, WorkflowRunResult accessors, as_agent() translation, and sub-workflow embedding.
Docs files to update
Repo: microsoft/semantic-kernel, path: agent-framework/.
| File |
What to change |
workflows/events.md |
Document the "intermediate" discriminator alongside "output". Mark "data" as a deprecated alias. Show how to filter on each type from a streaming run. |
workflows/executors.md |
Add a section on per-executor designation via WorkflowBuilder(final_output_from=[...], intermediate_output_from=[...]). State the build-time invariant: ctx.yield_output has no per-emission flag, designation does not vary per yield. |
workflows/as-agents.md |
Document that .as_agent() now forwards both output and intermediate events. Intermediates render as text_reasoning content; .text still returns only the terminal answer. |
workflows/advanced/sub-workflows.md |
Update the Output Behavior section: child intermediate emissions pipe through the parent stream, attributed to the embedding WorkflowExecutor id, and retain the intermediate label regardless of how the parent designates the WorkflowExecutor. |
workflows/advanced/agent-executor.md |
Document WorkflowRunResult.get_intermediate_outputs() next to existing get_outputs() usage. |
workflows/functional.md |
Same: add get_intermediate_outputs() next to get_outputs(). |
workflows/declarative.md |
Same: add get_intermediate_outputs() next to get_outputs(). |
workflows/orchestrations/handoff.md |
Document the default: final_output_from defaults to all participants. Show that intermediate_output_from=[X] implicitly demotes X from the default-final set (no overlap error). Use the new kwarg names throughout. |
workflows/orchestrations/sequential.md |
Same pattern: default is last participant; intermediate designation demotes from the default. Use the new kwarg names. |
workflows/orchestrations/magentic.md |
Replace any remaining intermediate_outputs=True style references with the new builder-time designation model (final_output_from, intermediate_output_from). |
workflows/orchestrations/concurrent.md and workflows/orchestrations/group-chat.md |
Sweep for output_participants / intermediate_participants and rename to final_output_from / intermediate_output_from. (No deprecation shim in orchestrations.) |
workflows/orchestrations/index.md |
If it summarizes the builder kwargs, update the names. |
integrations/ag-ui/workflows.md |
Where it discusses workflow_output custom events, clarify that both terminal and intermediate outputs flow through, and that intermediates surface as text_reasoning content on the agent boundary. |
Renames to sweep across all docs
output_executors -> final_output_from (core; old name deprecated)
intermediate_executors -> intermediate_output_from (core; old name deprecated)
output_participants -> final_output_from (orchestrations; clean break)
intermediate_participants -> intermediate_output_from (orchestrations; clean break)
Things to call out explicitly in the prose
- Per-executor / per-participant designation is build-time. There is no
ctx.yield_intermediate(...) API; the same ctx.yield_output(...) call is labeled based on the builder's designation list.
Workflow.to_dict() keeps the legacy wire keys output_executors / intermediate_executors for checkpoint compatibility. This asymmetry is intentional. If checkpoint format is documented anywhere, do not "fix" it.
- For orchestrations,
intermediate_output_from is usable on its own and implicitly demotes listed participants from the default-final set. The earlier overlap-rejection behavior was a bug.
Reference material for the docs agent
Out of scope
- Code changes in
microsoft/agent-framework.
- Migrating any checkpoint payloads.
- Adding a
ctx.yield_intermediate API or any per-emission labeling.
Context
PR #5623 (merged 2026-05-19) reshapes how workflows and orchestrations distinguish terminal answers from observational/progress emissions, renames the relevant builder kwargs, and adds new accessors. The docs at
microsoft/semantic-kernel(agent-framework/path) need a refresh to match.This issue is scoped to docs only. No code changes.
PR: #5623
Summary of what changed in code
WorkflowEvent.type == "intermediate"joins"output"(terminal). Legacy"data"is now a deprecated alias for"intermediate".WorkflowBuilder(final_output_from=[...], intermediate_output_from=[...]). Designation is fixed at build time.ctx.yield_output(...)has no per-emission flag, and an executor cannot vary the label per yield.WorkflowRunResult.get_intermediate_outputs()alongsideget_outputs().workflow.as_agent()boundary. Now forwards bothoutputandintermediateevents (explicit allowlistAGENT_FORWARDED_EVENT_TYPES). Intermediates render astext_reasoningcontent; existing.textstill returns only the terminal answer.WorkflowExecutor(sub-workflow embedding). Child intermediate emissions now bubble up through the parent's event stream, attributed to theWorkflowExecutor's own id (preserves encapsulation), and keep theintermediatelabel regardless of how the parent designates theWorkflowExecutor.agent_framework):output_executors->final_output_from,intermediate_executors->intermediate_output_from. Old names still accepted withDeprecationWarning. Supplying both old and new raisesTypeError. Serialized form (Workflow.to_dict()) intentionally keeps the legacy wire keysoutput_executors/intermediate_executorsfor checkpoint compat.agent_framework_orchestrations):output_participants->final_output_from,intermediate_participants->intermediate_output_from. Clean break, no shim (pre-1.0 package).HandoffBuilderdefaultsfinal_output_fromto every participant;SequentialBuilderdefaults to the last participant. Supplyingintermediate_output_from=[X]now implicitly demotesXout of the default-final set (previously raised an overlap error).python/samples/03-workflows/control-flow/intermediate_vs_terminal_outputs.pywalks explicit designation, streaming consumption,WorkflowRunResultaccessors,as_agent()translation, and sub-workflow embedding.Docs files to update
Repo:
microsoft/semantic-kernel, path:agent-framework/.workflows/events.md"intermediate"discriminator alongside"output". Mark"data"as a deprecated alias. Show how to filter on each type from a streaming run.workflows/executors.mdWorkflowBuilder(final_output_from=[...], intermediate_output_from=[...]). State the build-time invariant:ctx.yield_outputhas no per-emission flag, designation does not vary per yield.workflows/as-agents.md.as_agent()now forwards bothoutputandintermediateevents. Intermediates render astext_reasoningcontent;.textstill returns only the terminal answer.workflows/advanced/sub-workflows.mdWorkflowExecutorid, and retain theintermediatelabel regardless of how the parent designates theWorkflowExecutor.workflows/advanced/agent-executor.mdWorkflowRunResult.get_intermediate_outputs()next to existingget_outputs()usage.workflows/functional.mdget_intermediate_outputs()next toget_outputs().workflows/declarative.mdget_intermediate_outputs()next toget_outputs().workflows/orchestrations/handoff.mdfinal_output_fromdefaults to all participants. Show thatintermediate_output_from=[X]implicitly demotesXfrom the default-final set (no overlap error). Use the new kwarg names throughout.workflows/orchestrations/sequential.mdworkflows/orchestrations/magentic.mdintermediate_outputs=Truestyle references with the new builder-time designation model (final_output_from,intermediate_output_from).workflows/orchestrations/concurrent.mdandworkflows/orchestrations/group-chat.mdoutput_participants/intermediate_participantsand rename tofinal_output_from/intermediate_output_from. (No deprecation shim in orchestrations.)workflows/orchestrations/index.mdintegrations/ag-ui/workflows.mdworkflow_outputcustom events, clarify that both terminal and intermediate outputs flow through, and that intermediates surface astext_reasoningcontent on the agent boundary.Renames to sweep across all docs
output_executors->final_output_from(core; old name deprecated)intermediate_executors->intermediate_output_from(core; old name deprecated)output_participants->final_output_from(orchestrations; clean break)intermediate_participants->intermediate_output_from(orchestrations; clean break)Things to call out explicitly in the prose
ctx.yield_intermediate(...)API; the samectx.yield_output(...)call is labeled based on the builder's designation list.Workflow.to_dict()keeps the legacy wire keysoutput_executors/intermediate_executorsfor checkpoint compatibility. This asymmetry is intentional. If checkpoint format is documented anywhere, do not "fix" it.intermediate_output_fromis usable on its own and implicitly demotes listed participants from the default-final set. The earlier overlap-rejection behavior was a bug.Reference material for the docs agent
python/samples/03-workflows/control-flow/intermediate_vs_terminal_outputs.pypython/samples/03-workflows/orchestrations/*.py(already updated to the new kwarg names; use as authoritative examples)ctx.yield_output,WorkflowEvent.output,WorkflowEvent.intermediatecarry the per-executor invariant.Out of scope
microsoft/agent-framework.ctx.yield_intermediateAPI or any per-emission labeling.