# IWorkflowRunner

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/api/tracon.iworkflowrunner/
> Summary: IWorkflowRunner: Reads the workflow catalog and runs workflows.

<div class="api-provenance">Namespace Tracon · Assembly <code>Tracon.Abstractions.dll</code></div>

Reads the workflow catalog and runs workflows.

```csharp
public interface IWorkflowRunner
```

## Remarks

The abstraction lives in `Tracon.Abstractions` because the HTTP
layer runs workflows but does **not** depend on the
`Tracon.Workflows` package. This is the same pattern the MCP
package follows: the workflow engine stays an
optional package, and a consumer who does not use it does not pull in a
130-type execution engine.

Call this interface to run a workflow in process; the `Tracon.Workflows` package
supplies the implementation, so do not implement or replace it.

The contract carries no Microsoft Agent Framework type. Events flow
through Tracon's own [RunEvent](/api/tracon.runevent/) type; the conversion from
MAF events happens inside `Tracon.Workflows`.

**Delivery guarantee — AT-LEAST-ONCE, on [IWorkflowRunner.ResumeStreamingAsync](/api/tracon.iworkflowrunner/#Tracon_IWorkflowRunner_ResumeStreamingAsync_Tracon_WorkflowResumeRequest_System_Threading_CancellationToken_)
specifically.** Resuming from a run's LATEST checkpoint after it has
already completed does not re-run anything — there is nothing left to do. But
resuming from an EARLIER checkpoint (the shape a real crash recovery takes)
replays every super-step from that point forward, including any
`AddWorkflowFunction<T>` handler node in them, with the SAME
input — this is exactly the reason a workflow function handler with a real
side effect must be idempotent (see `AddWorkflowFunction<T>`'s
own remarks, where this was originally documented). [IWorkflowRunner.RunStreamingAsync](/api/tracon.iworkflowrunner/#Tracon_IWorkflowRunner_RunStreamingAsync_Tracon_WorkflowRunRequest_System_Threading_CancellationToken_)
and [IWorkflowRunner.RespondStreamingAsync](/api/tracon.iworkflowrunner/#Tracon_IWorkflowRunner_RespondStreamingAsync_Tracon_WorkflowRespondRequest_System_Threading_CancellationToken_) carry no such guarantee of their own:
each opens a fresh run and does not replay prior work.

## Methods

### <a id="Tracon_IWorkflowRunner_GetAsync_System_String_System_Threading_CancellationToken_"></a> GetAsync\(string, CancellationToken\)

Fetches a single workflow's summary.

```csharp
ValueTask<WorkflowDescriptor?> GetAsync(string name, CancellationToken cancellationToken = default)
```

#### Parameters

`name` [string](https://learn.microsoft.com/dotnet/api/system.string)

The workflow name.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<[WorkflowDescriptor](/api/tracon.workflowdescriptor/)?\>

The summary; [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) if it does not exist.

### <a id="Tracon_IWorkflowRunner_GetGraphAsync_System_String_System_Threading_CancellationToken_"></a> GetGraphAsync\(string, CancellationToken\)

Compiles a workflow and extracts its graph.

```csharp
ValueTask<WorkflowGraph?> GetGraphAsync(string name, CancellationToken cancellationToken = default)
```

#### Parameters

`name` [string](https://learn.microsoft.com/dotnet/api/system.string)

The workflow name.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<[WorkflowGraph](/api/tracon.workflowgraph/)?\>

The graph; [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) if the workflow is not in the catalog.

#### Remarks

The graph is **actually compiled**: the helper nodes added
by prebuilt patterns are visible only after compilation, and the
executor identifiers in run events come from there too. Compilation
makes no agent call, it only wires up the wrappers.

### <a id="Tracon_IWorkflowRunner_ListAsync_System_Threading_CancellationToken_"></a> ListAsync\(CancellationToken\)

Lists the workflows in the catalog (defined in code + database).

```csharp
ValueTask<IReadOnlyList<WorkflowDescriptor>> ListAsync(CancellationToken cancellationToken = default)
```

#### Parameters

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<[IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[WorkflowDescriptor](/api/tracon.workflowdescriptor/)\>\>

The summaries.

### <a id="Tracon_IWorkflowRunner_ListPendingRequestsAsync_System_Guid_System_Threading_CancellationToken_"></a> ListPendingRequestsAsync\(Guid, CancellationToken\)

Lists a run's pending human-input requests.

```csharp
ValueTask<IReadOnlyList<WorkflowPendingRequest>> ListPendingRequestsAsync(Guid runId, CancellationToken cancellationToken = default)
```

#### Parameters

`runId` [Guid](https://learn.microsoft.com/dotnet/api/system.guid)

The run identifier.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<[IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[WorkflowPendingRequest](/api/tracon.workflowpendingrequest/)\>\>

The pending requests; an empty list if none.

#### Exceptions

 [TraconException](/api/tracon.traconexception/)

The run does not exist or belongs to another tenant.

### <a id="Tracon_IWorkflowRunner_ListRequestsAsync_Tracon_WorkflowRequestQuery_System_Threading_CancellationToken_"></a> ListRequestsAsync\(WorkflowRequestQuery, CancellationToken\)

Lists the human requests the caller's tenant is waiting on, across runs.

```csharp
ValueTask<IReadOnlyList<WorkflowPendingRequest>> ListRequestsAsync(WorkflowRequestQuery query, CancellationToken cancellationToken = default)
```

#### Parameters

`query` [WorkflowRequestQuery](/api/tracon.workflowrequestquery/)

Which requests, and which page.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<[IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[WorkflowPendingRequest](/api/tracon.workflowpendingrequest/)\>\>

The requests, oldest first, one per logical request: the same request id in the same session
is listed once, under the newest run that still waits on it.

#### Remarks

Each item carries what [IWorkflowRunner.ListPendingRequestsAsync](/api/tracon.iworkflowrunner/#Tracon_IWorkflowRunner_ListPendingRequestsAsync_System_Guid_System_Threading_CancellationToken_) returns and the workflow name,
the session, the expiry and whether the request was answered.

The default implementation returns an empty list. An implementation written before this
member existed keeps compiling; it lists nothing here.

### <a id="Tracon_IWorkflowRunner_RespondStreamingAsync_Tracon_WorkflowRespondRequest_System_Threading_CancellationToken_"></a> RespondStreamingAsync\(WorkflowRespondRequest, CancellationToken\)

Responds to a pending request and resumes the run from its checkpoint.

```csharp
IAsyncEnumerable<RunEvent> RespondStreamingAsync(WorkflowRespondRequest request, CancellationToken cancellationToken = default)
```

#### Parameters

`request` [WorkflowRespondRequest](/api/tracon.workflowrespondrequest/)

The response.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [IAsyncEnumerable](https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerable\-1)<[RunEvent](/api/tracon.runevent/)\>

The ordered event stream.

#### Remarks

Resuming opens a **new run record**; the same rule as
[IWorkflowRunner.ResumeStreamingAsync](/api/tracon.iworkflowrunner/#Tracon_IWorkflowRunner_ResumeStreamingAsync_Tracon_WorkflowResumeRequest_System_Threading_CancellationToken_). The response is matched to the
request republished from the checkpoint by identifier.

### <a id="Tracon_IWorkflowRunner_ResumeStreamingAsync_Tracon_WorkflowResumeRequest_System_Threading_CancellationToken_"></a> ResumeStreamingAsync\(WorkflowResumeRequest, CancellationToken\)

Resumes from a checkpoint and streams its events.

```csharp
IAsyncEnumerable<RunEvent> ResumeStreamingAsync(WorkflowResumeRequest request, CancellationToken cancellationToken = default)
```

#### Parameters

`request` [WorkflowResumeRequest](/api/tracon.workflowresumerequest/)

The resume request.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [IAsyncEnumerable](https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerable\-1)<[RunEvent](/api/tracon.runevent/)\>

The ordered event stream.

#### Remarks

Resuming opens a **new run record**. Reopening the same
row would break the event stream's append-only rule and would
leave "when did this run end" unanswered.

### <a id="Tracon_IWorkflowRunner_RunStreamingAsync_Tracon_WorkflowRunRequest_System_Threading_CancellationToken_"></a> RunStreamingAsync\(WorkflowRunRequest, CancellationToken\)

Runs a workflow and streams its events.

```csharp
IAsyncEnumerable<RunEvent> RunStreamingAsync(WorkflowRunRequest request, CancellationToken cancellationToken = default)
```

#### Parameters

`request` [WorkflowRunRequest](/api/tracon.workflowrunrequest/)

The run request.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [IAsyncEnumerable](https://learn.microsoft.com/dotnet/api/system.collections.generic.iasyncenumerable\-1)<[RunEvent](/api/tracon.runevent/)\>

The ordered event stream.

#### Remarks

The first event is always [RunEventType.RunStarted](/api/tracon.runeventtype/), and
its [RunEvent.RunId](/api/tracon.runevent/#Tracon_RunEvent_RunId) field carries the run identifier; the
caller learns the identifier from the stream's first frame.

### <a id="Tracon_IWorkflowRunner_ValidateResponseAsync_Tracon_WorkflowRespondRequest_System_Threading_CancellationToken_"></a> ValidateResponseAsync\(WorkflowRespondRequest, CancellationToken\)

Checks a response against the pending request it answers, without starting a run.

```csharp
ValueTask<string?> ValidateResponseAsync(WorkflowRespondRequest request, CancellationToken cancellationToken = default)
```

#### Parameters

`request` [WorkflowRespondRequest](/api/tracon.workflowrespondrequest/)

The response to check.

`cancellationToken` [CancellationToken](https://learn.microsoft.com/dotnet/api/system.threading.cancellationtoken)

The cancellation token.

#### Returns

 [ValueTask](https://learn.microsoft.com/dotnet/api/system.threading.tasks.valuetask\-1)<[string](https://learn.microsoft.com/dotnet/api/system.string)?\>

A sentence that names the missing or unreadable field when the response cannot be
translated to the type the request's port expects; otherwise [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null).
It is also [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) when the check cannot be made before a run starts:
the run or the request is not found, or the run is not waiting for input.
[IWorkflowRunner.RespondStreamingAsync](/api/tracon.iworkflowrunner/#Tracon_IWorkflowRunner_RespondStreamingAsync_Tracon_WorkflowRespondRequest_System_Threading_CancellationToken_) reports those.

#### Remarks

The HTTP layer calls this before the event stream opens, so a response of the wrong
shape is refused with `400` and no run row is opened.
[IWorkflowRunner.RespondStreamingAsync](/api/tracon.iworkflowrunner/#Tracon_IWorkflowRunner_RespondStreamingAsync_Tracon_WorkflowRespondRequest_System_Threading_CancellationToken_) applies the same rule when the request is
republished and fails the run it opened: a caller that skips this check is refused
too, but only after a run has started.

The default implementation returns [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null). An implementation written
before this member keeps compiling and keeps reporting a wrong response on the stream.
