Skip to content

[dotnet-code] Clarify router type handling internals #438

Closed

Description

@github-actions

Summary

Clarifies the internal workflow message router metadata path by extracting the runtime-type substitution into typeHandlingInfo.forRuntimeType, matching the corresponding .NET TypeHandlingInfo shape more closely. This makes future .NET-to-Go routing ports easier to compare while preserving the existing cached interface-handler behavior.

.NET Reference

  • dotnet/src/Microsoft.Agents.AI.Workflows/Execution/MessageRouter.cs - TypeHandlingInfo.ForDerviedType creates derived runtime-type metadata when caching assignable handler matches.

Public API and Behavior

No public Go API changed. No intentional behavior change was made.

Tests

  • Added TestMessageRouterCachedInterfaceHandlerPreservesAutoOutput to lock existing cached interface-handler metadata behavior.
  • Ran go test ./workflow.
  • Ran go test ./....

Notes

Rejected candidates from the random .NET sample:

  • dotnet/src/Shared/Workflows/Execution/WorkflowFactory.cs - sample/shared factory code with no small production Go SDK counterpart cleanup.
  • dotnet/src/Microsoft.Agents.AI.Workflows/Execution/StateScope.cs - Go workflow/internal/execution/state.go is already structurally close for the sampled methods; no safer internal cleanup found.
  • dotnet/src/Microsoft.Agents.AI.Workflows/Execution/ConcurrentEventSink.cs - Go workflow/internal/execution/execution.go already has the minimal sink shape plus Go-specific concurrency handling, so refactoring risk outweighed portability value.

Generated by .NET-to-Go Code Portability Refactoring Agent · 315.5 AIC · ⌖ 31 AIC · ⊞ 20.8K · ◷


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-code-router-type-info-fcdf0e56f4c7648f.

Click here to create the pull request

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

Show patch preview (80 of 80 lines)
From e9cc3e18f6290358f833d482b5393e6b350d55ab Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Mon, 6 Jul 2026 22:50:59 +0000
Subject: [PATCH] Clarify router type handling internals

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 workflow/route.go      |  7 ++++++-
 workflow/route_test.go | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/workflow/route.go b/workflow/route.go
index ca235e975..fa89736fe 100644
--- a/workflow/route.go
+++ b/workflow/route.go
@@ -183,6 +183,11 @@ type typeHandlingInfo struct {
 	autoOutput  bool
 }
 
+func (info typeHandlingInfo) forRuntimeType(runtimeType reflect.Type) typeHandlingInfo {
+	info.runtimeType = runtimeType
+	return info
+}
+
 // newMessageRouter creates a router and indexes typed handlers by TypeID.
 func newMessageRouter(handlers map[reflect.Type]MessageHandlerFunc, handlerOutputTypes map[reflect.Type]reflect.Type, catchAll CatchAllFunc) *messageRouter {
 	outputTypes := make(map[reflect.Type]struct{}, len(handlerOutputTypes))
@@ -309,7 +314,7 @@ func (mr *messageRouter) findHandler(messageType reflect.Type) (typeHandlingInfo
 	for _, interfaceType := range mr.interfaceHandlers {
 		if messageType.AssignableTo(interfaceType) {
 			info := mr.typedHandlers[interfaceType]
-			info.runtimeType = messageType
+			info = info.forRuntimeType(messageType)
 			mr.typeInfos.Store(typeID, info)
 			return info, true
 		}
diff --git a/workflow/route_test.go b/workflow/route_test.go
index 6377f512b..6ac0aa7b4 100644
--- a/workflow/route_test.go
+++ b/workflow/route_test.go
@@ -110,3 +110,35 @@ func TestMessageRouterRoutesPortableValueAfterInterfaceMatchIsCached(t *testing.
 		t.Fatalf("RouteMessage portable result = %v, want portable", result.result)
 	}
 }
+
+func TestMessageRouterCachedInterfaceHandlerPreservesAutoOutput(t *testing.T) {
+	var rb RouteBuilder
+	rb.AddHandlerRaw(reflect.TypeFor[route
... (truncated)

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