[BREAKING] refactor: Fix unintuitive binding of StreamAsync (#1930)

In #1551 we added a mechanism to open a Streaming workflow run without providing any input. This caused unintuitive behaviour when passing a string as input without providing a runId, resulting in the input being misinterpreted as the runId and the workflow not executing.

As well, the name caused confusion about why the Workflow was not running when using the input-less StreamAsync (since the Workflow cannot run without any messages to drive its execution).
This commit is contained in:
Jacob Alber
2025-11-05 12:26:46 -05:00
committed by GitHub
Unverified
parent 14aee7e334
commit b8a55dccb4
3 changed files with 7 additions and 6 deletions
@@ -12,14 +12,15 @@ namespace Microsoft.Agents.AI.Workflows;
public interface IWorkflowExecutionEnvironment
{
/// <summary>
/// Initiates a streaming run of the specified workflow without sending any initial input.
/// Initiates a streaming run of the specified workflow without sending any initial input. Note that the starting
/// <see cref="Executor"/> will not be invoked until an input message is received.
/// </summary>
/// <param name="workflow">The workflow to execute. Cannot be null.</param>
/// <param name="runId">An optional identifier for the run. If null, a new run identifier will be generated.</param>
/// <param name="cancellationToken">A cancellation token that can be used to cancel the streaming operation.</param>
/// <returns>A ValueTask that represents the asynchronous operation. The result contains a StreamingRun object for accessing
/// the streamed workflow output.</returns>
ValueTask<StreamingRun> StreamAsync(Workflow workflow, string? runId = null, CancellationToken cancellationToken = default);
ValueTask<StreamingRun> OpenStreamAsync(Workflow workflow, string? runId = null, CancellationToken cancellationToken = default);
/// <summary>
/// Initiates an asynchronous streaming execution using the specified input.
@@ -37,7 +37,7 @@ public sealed class InProcessExecutionEnvironment : IWorkflowExecutionEnvironmen
}
/// <inheritdoc/>
public async ValueTask<StreamingRun> StreamAsync(
public async ValueTask<StreamingRun> OpenStreamAsync(
Workflow workflow,
string? runId = null,
CancellationToken cancellationToken = default)
@@ -41,9 +41,9 @@ public static class InProcessExecution
/// </summary>
internal static InProcessExecutionEnvironment Subworkflow { get; } = new(ExecutionMode.Subworkflow);
/// <inheritdoc cref="IWorkflowExecutionEnvironment.StreamAsync(Workflow, string?, CancellationToken)"/>
public static ValueTask<StreamingRun> StreamAsync(Workflow workflow, string? runId = null, CancellationToken cancellationToken = default)
=> Default.StreamAsync(workflow, runId, cancellationToken);
/// <inheritdoc cref="IWorkflowExecutionEnvironment.OpenStreamAsync(Workflow, string?, CancellationToken)"/>
public static ValueTask<StreamingRun> OpenStreamAsync(Workflow workflow, string? runId = null, CancellationToken cancellationToken = default)
=> Default.OpenStreamAsync(workflow, runId, cancellationToken);
/// <inheritdoc cref="IWorkflowExecutionEnvironment.StreamAsync{TInput}(Workflow, TInput, string?, CancellationToken)"/>
public static ValueTask<StreamingRun> StreamAsync<TInput>(Workflow workflow, TInput input, string? runId = null, CancellationToken cancellationToken = default) where TInput : notnull