Skip to content

Unify agent workflow responses as output events - #124

Merged
qmuntal merged 1 commit into
mainfrom
port-pr-3441-output-events
May 5, 2026
Merged

Unify agent workflow responses as output events#124
qmuntal merged 1 commit into
mainfrom
port-pr-3441-output-events

Conversation

@qmuntal

@qmuntal qmuntal commented May 5, 2026

Copy link
Copy Markdown
Member

Summary

Tests

  • go test ./...

Copilot AI review requested due to automatic review settings May 5, 2026 09:07
@github-actions

github-actions Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

API Consistency Review

Summary: This PR ports the spirit of microsoft/agent-framework PR #3441 (unify agent response events under the generic output-event hierarchy), but the approach diverges from what the upstream .NET implementation actually did.

What upstream .NET PR #3441 did

Upstream .NET Effect
AgentResponseUpdateEvent : WorkflowOutputEvent Typed event preserved, now also a WorkflowOutputEvent subclass
AgentResponseEvent : WorkflowOutputEvent Typed event preserved, now also a WorkflowOutputEvent subclass
WorkflowOutputEvent.Is<T>() / As<T>() Generic helpers added to the base event for ergonomic payload access

Consumers can still do if (evt is AgentResponseUpdateEvent e) { _ = e.Update; } — no inner cast required.

What this Go PR does

  • Removes ResponseUpdateEvent and ResponseEvent entirely from the public workflow package
  • Leaves only OutputEvent with Output any, with no typed helpers

Go consumers now need two nested type assertions to reach a response payload, which is more verbose than the upstream API intends and could make cross-language documentation and samples harder to keep aligned.

Suggested alignment options

  1. Keep typed event structs (analogous to AgentResponseUpdateEvent / AgentResponseEvent) even if they can't inherit OutputEvent — emit them from the inproc runner in parallel with or instead of OutputEvent for response payloads.
  2. Add free-function helpers like workflow.OutputEventAs[T](e OutputEvent) (T, bool) to match the ergonomics of .NET's WorkflowOutputEvent.Is<T>() / As<T>().

See inline comment on workflow/event.go for details.

Generated by Go API Consistency Review Agent for issue #124 · ● 619K ·

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generated by Go API Consistency Review Agent for issue #124 · ● 619K

Comment thread workflow/event.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR unifies workflow-hosted agent responses under workflow.OutputEvent instead of the dedicated ResponseUpdateEvent / ResponseEvent types, and updates the provider, examples, and tests to consume the new event shape. It affects core workflow event semantics, hosted-agent behavior, and the workflow-backed agent provider.

Changes:

  • Remove dedicated workflow response event types and route hosted-agent updates/responses through OutputEvent.
  • Update workflowprovider to translate hosted-agent OutputEvent payloads into agent response updates.
  • Refresh examples and tests to look for OutputEvent payload types instead of the removed event types.
Show a summary per file
File Description
workflow/inproc/context.go Removes special handling that previously converted yielded agent responses into dedicated workflow events.
workflow/event.go Deletes the exported ResponseUpdateEvent and ResponseEvent types from the public workflow API.
examples/03-workflows/_start-here/03_agent_workflow_patterns/main.go Updates the sample to read hosted-agent streaming updates from OutputEvent.
examples/03-workflows/_start-here/02_agents_in_workflows/main.go Updates the sample to read hosted-agent streaming updates from OutputEvent.
agent/provider/workflowprovider/workflow.go Reworks workflow-event-to-agent-update translation around OutputEvent payloads.
agent/provider/workflowprovider/workflow_test.go Adjusts provider tests for the new output-event-based response flow.
agent/hosting/workflowhosting/workflow.go Changes hosted agents to emit streaming updates and aggregated responses as OutputEvents.
agent/hosting/workflowhosting/workflow_test.go Updates hosted-agent tests to collect typed payloads from OutputEvent.
agent/hosting/workflowhosting/inprocess_execution_test.go Updates in-process execution tests and adds coverage for hosted-agent outputs without WithOutputFrom.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (2)

workflow/inproc/context.go:496

  • Removing the *agent.ResponseUpdate/*agent.Response special-casing here means ctx.YieldOutput(...) from a non-output executor is now dropped silently unless the binding is also registered with WithOutputFrom. That is a behavior regression for existing plain executors that relied on agent-style outputs being surfaced without declaring workflow outputs.
		YieldOutput: func(output any) error {
			// Check if this executor can output
			if _, ok := proc.wf.OutputExecutors[executorID]; ok {
				return proc.AddEvent(ctx, workflow.OutputEvent{
					ExecutorID: executorID,
					Output:     output,
				})

agent/hosting/workflowhosting/workflow.go:461

  • This has the same compatibility problem as the streaming path above: a hosted agent that is not in WithOutputFrom will now still surface a workflow.OutputEvent here, so consumers listening for declared workflow outputs start receiving an extra aggregated *agent.Response from every hosted agent in the graph.
	if h.cfg.EmitResponseEvents {
		if err := wctx.AddEvent(workflow.OutputEvent{ExecutorID: h.id, Output: &resp}); err != nil {
  • Files reviewed: 9/9 changed files
  • Comments generated: 3

Comment thread workflow/event.go
Comment thread agent/hosting/workflowhosting/workflow.go
Comment thread agent/provider/workflowprovider/workflow.go
@qmuntal

qmuntal commented May 5, 2026

Copy link
Copy Markdown
Member Author

Agent response events are a bit more difficult to consume with this change, as they need one additional type cast. On the other hand, there is now no possible confusion about which event will be emitted when there is an agent response. It is not possible to achieve 100% parity with .NET due to the lack of inheritance, so I've picked the side of consistency and clarity over verbosity.

@qmuntal
qmuntal requested a review from gdams May 5, 2026 09:24
@qmuntal
qmuntal enabled auto-merge (squash) May 5, 2026 13:56
@qmuntal
qmuntal merged commit 384a2e3 into main May 5, 2026
14 checks passed
@qmuntal
qmuntal deleted the port-pr-3441-output-events branch May 5, 2026 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants