microsoft / microsoft/agent-framework

.NET: [Feature]: .NET: Add per-RequestPort response composition mode

Open
#7,956 0 comments 0 reactions 1 assignee View on GitHub

@baywet is already working on this.

Since Sep 3, 2026.

.NET
Dominant language
Python
Stars
13.6k
Forks
2.3k
Avg merge
2d 45m
Merged PRs (30d)
358

Description

### Description

## Summary

Add an explicit per-`RequestPort` response composition mode so that a `RequestPort` can declare how a response should relate to the original request.

This is an upstream API dependency for:

```text id="gmv1a8"
microsoft/agent-framework-durable-extension#78
```

---

## Context

Durable Extension issue `microsoft/agent-framework-durable-extension#78` is exploring opt-in HITL response merging.

The current durable behavior forwards exactly the response supplied by the caller.

For example, if the original request is:

```json id="pysr8z"
{
"id": "ABC-123",
"inputNumber": "42",
"isApproved": false
}
```

and the approval response contains only:

```json id="xmw65y"
{
"isApproved": true
}
```

the downstream executor receives only the newly deserialized response payload, so fields omitted from the response are not preserved.

The durable-extension discussion converged on making this behavior explicit and opt-in per `RequestPort`, rather than introducing a durable-runtime-specific policy.

`RequestPort` and `RequestPortBinding` are defined by:

```text id="k2whju"
Microsoft.Agents.AI.Workflows
```

in this repository, while the durable extension consumes that package.

Therefore the response semantic cannot be declared on the owning type from the durable-extension repository alone.

---

## Proposed Contract

The direction discussed in `microsoft/agent-framework-durable-extension#78` is an explicit per-`RequestPort` mode with two initial behaviors:

* `ResponseOnly` — current behavior and the default. The supplied response is forwarded as-is.
* `ShallowOverlay` — preserve the original request and overlay top-level properties explicitly supplied by the response.

For `ShallowOverlay`:

* response-present top-level properties replace the original values
* omitted top-level properties preserve the original values
* explicit `null` replaces the original value
* nested objects and arrays are replaced wholesale rather than recursively merged

Recursive merge would remain out of scope for the initial contract.

The mode itself should remain runtime-neutral.

A runtime such as the durable extension could then consume the mode when handling suspension / resume without maintaining a separate shadow policy.

---

## Backward Compatibility

`ResponseOnly` would remain the default, preserving the existing `RequestPort` response behavior for callers that do not opt in.

This is intended as an additive API extension rather than a change to the current default semantics.

---

## Open Design Question

`RequestPort` supports arbitrary request and response CLR types, while `ShallowOverlay` is naturally defined for object-shaped payloads.

The applicability boundary therefore needs to be defined upstream.

In particular:

* Should `ShallowOverlay` only be valid when both serialized request and response are JSON objects?
* How should non-object payloads such as scalars or top-level arrays be handled?
* Should incompatible request / response shapes be rejected when the mode is declared, or only when a response is processed?

I would prefer to leave the exact public API shape to discussion here rather than introduce an extension-side workaround.

I'd be happy to take on the upstream API portion once the contract and API shape are agreed.

---

## Related

- Upstream API dependency for microsoft/agent-framework-durable-extension#78

### Code Sample

```markdown
N/A — the exact public API shape is intentionally left for discussion.
```

### Language/SDK

.NET

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.