mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
feat: WorkflowHostAgent forwards AgentResponseEvent unconditionally under Futures-on
Aligns the .NET Workflow-as-Agent surface with Python `as_agent`. Under `Futures.EnableAgentResponseOutputTaggingAndFiltering = true`, `WorkflowSession.InvokeStageAsync` now forwards `AgentResponseEvent` unconditionally — joining `AgentResponseUpdateEvent` in ignoring the host's `includeWorkflowOutputsInResponse` switch. That switch keeps governing the generic `WorkflowOutputEvent` path for non-AIAgent payloads, where it is further short-circuited by an `IsIntermediate()` check (tagged intermediate outputs always surface). Under Futures-off the legacy asymmetry is preserved: `AgentResponseUpdateEvent` always forwarded, `AgentResponseEvent` gated by `includeWorkflowOutputsInResponse`. Back-compat: with `Futures.EnableAgentResponseOutputTaggingAndFiltering` left at its default `false`, observable behavior is identical to before. `Futures` documentation gains a remark explaining the `Workflow.AsAIAgent()` interaction in both flag states. Runner fix ---------- `InProcessRunnerContext.YieldOutputAsync` now skips `Executor.CanOutput` for AgentResponse-shaped payloads under both Futures branches. `AIAgentHostExecutor` doesn't declare AgentResponse(Update) in its `Yields` set, so the historical legacy bypass had silently skipped the check; Phase 3's Futures-on path was running it and would reject AIAgent payloads. AIAgent-shaped payloads are now always a valid output shape, matching the legacy bypass semantics. Phase 4 follow-on ----------------- Switched the three orchestration-builder designation-replay loops to iterate `Dictionary.Keys` with a value lookup instead of constructing/destructuring `KeyValuePair<,>`. Cleaner shape and avoids the netstandard2.0 / net472 `KeyValuePair<,>.Deconstruct` unavailability that surfaced when this branch multi-TFM-built. Tests ----- `WorkflowHostSmokeTests.IntermediateForwarding` (new nested class, 6 tests): - intermediate AgentResponse forwarded past the include-outputs gate (Futures on) - terminal AgentResponse forwarded unconditionally (Futures on) - terminal AgentResponse gated by include flag (Futures off, legacy) - undesignated AIAgent executor emits no AgentResponseEvent under Futures-on - legacy bypass still emits AgentResponseEvent under Futures-off - intermediate tag is observable via `update.RawRepresentation` The class joins the `FuturesSerial` xUnit collection so the process-global flag is serialized against other Futures-toggling tests. 599/599 unit tests pass on net10.0 (593 baseline + 6 new). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
Jacob Alber
Unverified
parent
6f31e32df6
commit
508aeefb6b
@@ -520,7 +520,12 @@ internal sealed class WorkflowSession : AgentSession
|
||||
goto default;
|
||||
|
||||
case AgentResponseEvent agentResponse:
|
||||
if (!this._includeWorkflowOutputsInResponse)
|
||||
// Under Futures.EnableAgentResponseOutputTaggingAndFiltering=true, mirror
|
||||
// AgentResponseUpdateEvent's behavior: always forward, regardless of the
|
||||
// _includeWorkflowOutputsInResponse host flag. Under the legacy default,
|
||||
// keep today's behavior — gated by the include flag.
|
||||
if (!Futures.EnableAgentResponseOutputTaggingAndFiltering &&
|
||||
!this._includeWorkflowOutputsInResponse)
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
@@ -539,7 +544,11 @@ internal sealed class WorkflowSession : AgentSession
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (!this._includeWorkflowOutputsInResponse || updateMessages == null)
|
||||
// Same gating asymmetry as AgentResponseEvent: intermediate outputs are
|
||||
// forwarded unconditionally; terminal/untagged outputs require the host
|
||||
// to opt in via _includeWorkflowOutputsInResponse.
|
||||
if (updateMessages == null ||
|
||||
(!output.IsIntermediate() && !this._includeWorkflowOutputsInResponse))
|
||||
{
|
||||
goto default;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user