Skip to content

[dotnet-code] Consolidate portable value delayed decode helper #873

Description

@github-actions

Summary

Centralized the delayed JSON deserialization path used by PortableValue.Is into an unexported helper. This keeps the existing behavior while making the Go portable-value internals closer to the .NET PortableValue shape, where type-specific extraction flows through a deserialization helper.

.NET Reference

  • dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/PortableValueTests.cs - exercises PortableValue round-trips and delayed deserialization through typed extraction.

Public API and Behavior

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

Tests

  • go test ./workflow

Notes

Rejected candidates from the random sample:

  • dotnet/src/Microsoft.Agents.AI.Workflows/EdgeData.cs - Go edge internals expose Edge/EdgeConnection public fields, so matching the .NET EdgeData abstraction would risk public API churn.
  • dotnet/src/Microsoft.Agents.AI.A2A/A2AAgentOptions.cs - adding the .NET-style clone/options shape in Go would add public API rather than an internal cleanup.
  • dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/PowerFx/Functions/MessageFunction.cs - no narrow Go declarative/PowerFx counterpart exists to refactor without adding a missing feature.

Open [dotnet-code] PR check found only #860 for group chat dispatch, which does not cover this portable-value candidate.

Generated by .NET-to-Go Code Portability Refactoring Agent · gpt55 · 87.5 AIC · ⌖ 13.9 AIC · ⊞ 23.2K ·


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-portablevalue-helper-20260819-dd11a3c40492b4b9.

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 (52 lines)
From dd7a0a377ef15edd12e10f211a26c6f790340f7d Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Wed, 19 Aug 2026 22:35:21 +0000
Subject: [PATCH] Consolidate portable value delayed decode helper

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 workflow/portable.go | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/workflow/portable.go b/workflow/portable.go
index 885de2284..491704af9 100644
--- a/workflow/portable.go
+++ b/workflow/portable.go
@@ -134,6 +134,17 @@ func decodePortableJSONType(typ reflect.Type, raw json.RawMessage) (any, bool) {
 	return target.Elem().Interface(), true
 }
 
+func decodePortableJSONAs(typ reflect.Type, raw json.RawMessage) (any, bool) {
+	decoded, ok := decodePortableJSONType(typ, raw)
+	if !ok {
+		return nil, false
+	}
+	if decoded == nil || !reflect.TypeOf(decoded).AssignableTo(typ) {
+		return nil, false
+	}
+	return decoded, true
+}
+
 func decodePortableJSON[T any](raw json.RawMessage) (any, bool) {
 	var decoded T
 	if err := json.Unmarshal(raw, &decoded); err != nil {
@@ -160,13 +171,9 @@ func (v *PortableValue) Is(typ reflect.Type) bool {
 		// not a delayed deserialization
 		return v.any != nil && reflect.TypeOf(v.any).AssignableTo(typ)
 	}
-	target := reflect.New(typ)
 	// Either we have no cache, or the types are incompatible; see if we can deserialize to the requested type
-	if err := json.Unmarshal(raw, target.Interface()); err != nil {
-		return false
-	}
-	deserialized := target.Elem().Interface()
-	if deserialized == nil || !reflect.TypeOf(deserialized).AssignableTo(typ) {
+	deserialized, ok := decodePortableJSONAs(typ, raw)
+	if !ok {
 		return false
 	}
 	v.cache = deserialized
-- 
2.54.0

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