Skip to content

[dotnet-port-fixes] Suppress hosted response emission after cancellation #933

Description

@github-actions

Summary

Aligned workflow/agentworkflow hosting with the upstream .NET cancellation fix so a canceled hosted turn stops before emitting the aggregated agent.Response or forwarding final response messages. Added a focused regression test that cancels immediately after the last streamed update and asserts the hosted executor returns context.Canceled without emitting completion artifacts.

Ported .NET PRs

Breaking Changes

No.

Tests and Examples

  • go test ./workflow/agentworkflow -run 'TestHostedAgent_(EmitsResponseIfConfigured|CancellationSuppressesFinalResponseEmission)'
  • go test ./workflow/agentworkflow

Notes

  • This is a behavior-only parity port; it does not change the public Go API.
  • The selected upstream change was verified as a fix/test port with no public option, builder, default, or capability change.

Generated by .NET to Go Fixes and Test Porting Agent · gpt54 · 324.2 AIC · ⌖ 15.7 AIC · ⊞ 24.4K ·


Note

This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch dotnet-port-fixes-hosting-cancellation-2b7a906ab780bb7c.

Click here to create the pull request

To fix the permissions issue, go to SettingsActionsGeneral and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ

Show patch preview (139 of 139 lines)
From c3ba85636f5b098e950a1e242de12cb21386b9ef Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Fri, 28 Aug 2026 05:14:04 +0000
Subject: [PATCH] [dotnet-port-fixes] Suppress hosted response emission after
 cancellation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 workflow/agentworkflow/hosting.go      |  5 ++
 workflow/agentworkflow/hosting_test.go | 89 ++++++++++++++++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/workflow/agentworkflow/hosting.go b/workflow/agentworkflow/hosting.go
index b99dd5e28..cdd6192eb 100644
--- a/workflow/agentworkflow/hosting.go
+++ b/workflow/agentworkflow/hosting.go
@@ -430,6 +430,11 @@ func (h *hostExecutor) runAgentAndDispatch(wctx *workflow.Context, messages []*m
 		}
 		resp.Update(update)
 	}
+	// Match .NET hosting: if cancellation arrives after the last streamed update
+	// but before the turn is finalized, do not emit the aggregated completion.
+	if err := wctx.Err(); err != nil {
+		return err
+	}
 	resp.Coalesce()
 
 	// Stamp this hosting executor's name on every aggregated message,
diff --git a/workflow/agentworkflow/hosting_test.go b/workflow/agentworkflow/hosting_test.go
index 5c4b529c0..d20e8265a 100644
--- a/workflow/agentworkflow/hosting_test.go
+++ b/workflow/agentworkflow/hosting_test.go
@@ -175,6 +175,24 @@ func newContentAgent(updates ...*agent.ResponseUpdate) *agent.Agent {
 	)
 }
 
+func newCancelOnCompletionAgent(cancel context.CancelFunc) *agent.Agent {
+	run := func(ctx context.Context, _ []*message.Message, _ ...agent.Option) iter.Seq2[*agent.ResponseUpdate, error] {
+		return func(yield func(*agent.ResponseUpdate, error) bool) {
+			if !yield(&agent.ResponseUpdate{
+				Role:     message.RoleAssistant,
+				Contents: []message.Content{&message.TextContent{Text: "done"}},
+			}, nil) {
+				return
+			}
+			cancel()
+		}
+	}
+	return agent.New(
+		agent.ProviderConfig{ProviderName: "cancel-on-completion", Run: ru
... (truncated)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions