# WorkflowDefinition

> 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.workflowdefinition/
> Summary: WorkflowDefinition: Represents the full definition of a workflow, whether defined through the UI or in code.

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

Represents the full definition of a workflow, whether defined through the
UI or in code.

```csharp
public sealed record WorkflowDefinition : IEquatable<WorkflowDefinition>
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.workflowdefinition/">WorkflowDefinition</a></dd><dt>Implements</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.iequatable-1">IEquatable&lt;WorkflowDefinition&gt;</a></dd><dt>Inherited Members</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object.gettype">object.GetType()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.tostring">object.ToString()</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object)">object.Equals(object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.equals#system-object-equals(system-object-system-object)">object.Equals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.referenceequals">object.ReferenceEquals(object?, object?)</a>, <a href="https://learn.microsoft.com/dotnet/api/system.object.gethashcode">object.GetHashCode()</a></dd></dl>

## Remarks

A definition is a **graph**, not code: it only wires
together agents from the catalog. Users do not write new behavior, they
arrange existing behavior. A free-form graph (custom `Executor`
types) can only be defined in code, via `AddWorkflow(name, factory)`.

[WorkflowDefinition.AgentNames](/api/tracon.workflowdefinition/#Tracon_WorkflowDefinition_AgentNames) is a list of *names* only. Each name must
resolve to an agent in the catalog; if it does not, compilation fails.
The same rule applies to [AgentDefinition.ToolNames](/api/tracon.agentdefinition/#Tracon_AgentDefinition_ToolNames) and draws
the same security boundary.

## Constructors

### <a id="Tracon_WorkflowDefinition__ctor"></a> WorkflowDefinition\(\)

```csharp
public WorkflowDefinition()
```

## Properties

### <a id="Tracon_WorkflowDefinition_AgentNames"></a> AgentNames

Gets the agent names to enter the graph. Order is meaningful for
[WorkflowKind.Sequential](/api/tracon.workflowkind/); for other kinds it defines the
participant set.

```csharp
public IReadOnlyList<string> AgentNames { get; init; }
```

#### Property Value

 [IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[string](https://learn.microsoft.com/dotnet/api/system.string)\>

### <a id="Tracon_WorkflowDefinition_Description"></a> Description

Gets the short description of what the workflow does.

```csharp
public string? Description { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_WorkflowDefinition_DisplayName"></a> DisplayName

Gets the display name shown in the UI. `Name` is used if left empty.

```csharp
public string? DisplayName { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_WorkflowDefinition_HandoffInstructions"></a> HandoffInstructions

Gets the extra instruction that tells the model how to decide on a
handoff. Used only for [WorkflowKind.Handoff](/api/tracon.workflowkind/).

```csharp
public string? HandoffInstructions { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_WorkflowDefinition_Kind"></a> Kind

Gets the built-in pattern to use.

```csharp
public required WorkflowKind Kind { get; init; }
```

#### Property Value

 [WorkflowKind](/api/tracon.workflowkind/)

### <a id="Tracon_WorkflowDefinition_ManagerAgentName"></a> ManagerAgentName

Gets the manager agent's name. Required for
[WorkflowKind.Magentic](/api/tracon.workflowkind/), unused in other patterns.

```csharp
public string? ManagerAgentName { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_WorkflowDefinition_MaxIterations"></a> MaxIterations

Gets the maximum number of turns. The only guard against an infinite
loop in the [WorkflowKind.GroupChat](/api/tracon.workflowkind/),
[WorkflowKind.Handoff](/api/tracon.workflowkind/), and [WorkflowKind.Magentic](/api/tracon.workflowkind/)
patterns.

```csharp
public int? MaxIterations { get; init; }
```

#### Property Value

 [int](https://learn.microsoft.com/dotnet/api/system.int32)?

### <a id="Tracon_WorkflowDefinition_Name"></a> Name

Gets the workflow's unique name. Serves as the key in the catalog and in API routes.

```csharp
public required string Name { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)

### <a id="Tracon_WorkflowDefinition_Nodes"></a> Nodes

Gets the ordered node list for a [WorkflowKind.Sequential](/api/tracon.workflowkind/)
workflow that mixes agent and function nodes.

```csharp
public IReadOnlyList<WorkflowNodeReference> Nodes { get; init; }
```

#### Property Value

 [IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[WorkflowNodeReference](/api/tracon.workflownodereference/)\>

#### Remarks

Empty for every definition that does not use a function node - which
keeps [WorkflowDefinition.AgentNames](/api/tracon.workflowdefinition/#Tracon_WorkflowDefinition_AgentNames) driving the graph exactly as before this
field existed. When non-empty, [WorkflowDefinition.Kind](/api/tracon.workflowdefinition/#Tracon_WorkflowDefinition_Kind) must be
[WorkflowKind.Sequential](/api/tracon.workflowkind/) and [WorkflowDefinition.AgentNames](/api/tracon.workflowdefinition/#Tracon_WorkflowDefinition_AgentNames) must
be empty; the validator in `Tracon.Core` enforces both
rules. Microsoft Agent Framework's ready-made builders for the other
four patterns (`Concurrent`, `Handoff`, `GroupChat`,
`Magentic`) accept only agents, so a function node cannot enter
those graphs without hand-writing their orchestration logic - out of
scope.

Whether each function name is actually registered is checked at
*save* time (the HTTP layer, against the function registry)
and again at *compile* time, unlike agent names - which are
checked only at compile time because the agent catalog can change
between the two. The function registry cannot: it is fixed for the
lifetime of the process, so checking early gives an honest guarantee.

A function node may carry [WorkflowNodeReference.Settings](/api/tracon.workflownodereference/#Tracon_WorkflowNodeReference_Settings), checked
the same way against the settings type its function declares
(the save-time settings check) and read again at
compile time, because that type can change between deployments.

A chain of agents only may be stored either way: as [WorkflowDefinition.AgentNames](/api/tracon.workflowdefinition/#Tracon_WorkflowDefinition_AgentNames)
or as [WorkflowDefinition.Nodes](/api/tracon.workflowdefinition/#Tracon_WorkflowDefinition_Nodes), and the server accepts both. The console writes
[WorkflowDefinition.Nodes](/api/tracon.workflowdefinition/#Tracon_WorkflowDefinition_Nodes) only when the chain holds at least one function node.

### <a id="Tracon_WorkflowDefinition_Parameters"></a> Parameters

Gets the run parameters the workflow accepts. Empty for a workflow that
takes none.

```csharp
public IReadOnlyList<AgentParameter> Parameters { get; init; }
```

#### Property Value

 [IReadOnlyList](https://learn.microsoft.com/dotnet/api/system.collections.generic.ireadonlylist\-1)<[AgentParameter](/api/tracon.agentparameter/)\>

#### Remarks

A run supplies values for these names ([WorkflowRunRequest.Parameters](/api/tracon.workflowrunrequest/#Tracon_WorkflowRunRequest_Parameters)).
The set is the workflow's contract: each agent step receives the values
whose names its own schema declares, and binds them into its
instructions the way a direct run of that agent would. A name the
workflow declares but a step does not is dropped for that step.

Only the structure is checked when the definition is saved (valid,
unique names). Whether every participant's required parameters are
covered is checked when a run starts: the participants live in the agent
catalog, which can change after the workflow is saved.

A workflow defined in code (`AddWorkflow`) carries no definition and
therefore declares no parameters; a value supplied to it is rejected.
[AgentParameter.Kind](/api/tracon.agentparameter/#Tracon_AgentParameter_Kind) labels the value for the console only;
every value travels as a string.

### <a id="Tracon_WorkflowDefinition_RequestTimeout"></a> RequestTimeout

Gets how long a human request of this workflow may wait for an answer before the run that
waits on it is closed. [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) (the default) means it waits without limit.

```csharp
public TimeSpan? RequestTimeout { get; init; }
```

#### Property Value

 [TimeSpan](https://learn.microsoft.com/dotnet/api/system.timespan)?

#### Remarks

A run that waits for a human keeps its request event, its checkpoints and its input row
without limit, because answering needs them (a retention policy does not delete them while
the run waits). A limit is what lets those rows go: when the time passes the run is closed
[RunStatus.Failed](/api/tracon.runstatus/) with the error type `WorkflowRequestExpired`, or
[RunStatus.Completed](/api/tracon.runstatus/) without an error when every request it waited on was
answered, and the retention policy deletes its rows on its next round. An answer to a
run that was closed is refused with `400`.

The time counts from the moment the run published the request. A run that waits keeps the
limit of the definition version it recorded, so an edit made while it waits changes
neither the graph nor the limit. Must be from one minute to 365 days.

### <a id="Tracon_WorkflowDefinition_RequirePlanApproval"></a> RequirePlanApproval

Gets whether the plan the manager agent builds must be approved by a
human before execution starts. Applies only to
[WorkflowKind.Magentic](/api/tracon.workflowkind/).

```csharp
public bool RequirePlanApproval { get; init; }
```

#### Property Value

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

#### Remarks

When enabled, Microsoft Agent Framework publishes an external request
at the end of the first super-step; the run becomes
[RunStatus.AwaitingInput](/api/tracon.runstatus/) and its state is written to a
checkpoint. The response is given via
`POST /api/workflows/runs/{runId}/respond`: the plan is either
approved or sent back with revision text.

**Cost.** The manager agent runs again on every turn;
a revision request makes it rebuild the plan from scratch. The default
of [false](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) is deliberate: a run never stalls half-way
unless a definition opts in explicitly (the no-surprises rule).

### <a id="Tracon_WorkflowDefinition_ResponseMode"></a> ResponseMode

Gets how the workflow treats more than one answer to the same pending human request.
[WorkflowResponseMode.Branch](/api/tracon.workflowresponsemode/) (the default) opens a new run for every answer;
[WorkflowResponseMode.SingleAnswer](/api/tracon.workflowresponsemode/) allows one answer per request.

```csharp
public WorkflowResponseMode ResponseMode { get; init; }
```

#### Property Value

 [WorkflowResponseMode](/api/tracon.workflowresponsemode/)

#### Remarks

Applies to every kind. A stored definition's requests come from a manager agent's plan
approval ([WorkflowDefinition.RequirePlanApproval](/api/tracon.workflowdefinition/#Tracon_WorkflowDefinition_RequirePlanApproval)); a workflow defined in code chooses its mode
when it is registered.

A waiting run is answered under the mode of the definition version it recorded. Changing
the mode affects runs started after the change.

### <a id="Tracon_WorkflowDefinition_RunTimeout"></a> RunTimeout

Gets the longest time one run of this workflow may take.
[null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) (the default) uses the installation's
`Tracon:Workflows:RunTimeout`.

```csharp
public TimeSpan? RunTimeout { get; init; }
```

#### Property Value

 [TimeSpan](https://learn.microsoft.com/dotnet/api/system.timespan)?

#### Remarks

The value replaces the installation's run timeout for this workflow only,
and it behaves the same way: the deadline starts when the run starts (a
wait for a `MaxConcurrentRuns` slot counts too), it cancels the token
every node is given, and a run that reaches it ends
[RunStatus.Canceled](/api/tracon.runstatus/) with an error that names this field.

**It may only shorten the installation's value unless the host allows
more.** A running workflow holds one of the slots that every tenant
shares, so the host decides how long one may hold it:
`Tracon:Workflows:MaxRunTimeout` is the ceiling. While it is not set, a
value above `Tracon:Workflows:RunTimeout` is refused when the definition
is saved (`400`). A stored value above a ceiling that was lowered later
still runs, cut to the ceiling.

Must be from one millisecond to about 49.7 days. A node's own timeout
([WorkflowNodeReference.Timeout](/api/tracon.workflownodereference/#Tracon_WorkflowNodeReference_Timeout)) is not checked against this
value: the two answer different questions, and whichever ends first stops the
node.

A [WorkflowKind.Sequential](/api/tracon.workflowkind/) chain bounds each step with
[WorkflowNodeReference.Timeout](/api/tracon.workflownodereference/#Tracon_WorkflowNodeReference_Timeout); the other patterns
([WorkflowDefinition.AgentNames](/api/tracon.workflowdefinition/#Tracon_WorkflowDefinition_AgentNames)) have no nodes, so this value and the installation's
`Tracon:AgentGraph:ChildDeadline` bound them.

### <a id="Tracon_WorkflowDefinition_TenantId"></a> TenantId

Gets the tenant the definition belongs to. [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) for workflows defined in code.

```csharp
public string? TenantId { get; init; }
```

#### Property Value

 [string](https://learn.microsoft.com/dotnet/api/system.string)?

### <a id="Tracon_WorkflowDefinition_UpdatedAt"></a> UpdatedAt

Gets the last modification time (UTC).

```csharp
public DateTimeOffset? UpdatedAt { get; init; }
```

#### Property Value

 [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset)?

### <a id="Tracon_WorkflowDefinition_Version"></a> Version

Gets the definition version. Increments by one on every save and is never
reused: the store keeps every version (see [IWorkflowDefinitionStore](/api/tracon.iworkflowdefinitionstore/)).

```csharp
public int Version { get; init; }
```

#### Property Value

 [int](https://learn.microsoft.com/dotnet/api/system.int32)

## Methods

### <a id="Tracon_WorkflowDefinition_Equals_System_Object_"></a> Equals\(object?\)

```csharp
public override bool Equals(object? obj)
```

#### Parameters

`obj` [object](https://learn.microsoft.com/dotnet/api/system.object)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_WorkflowDefinition_Equals_Tracon_WorkflowDefinition_"></a> Equals\(WorkflowDefinition?\)

```csharp
public bool Equals(WorkflowDefinition? other)
```

#### Parameters

`other` [WorkflowDefinition](/api/tracon.workflowdefinition/)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_WorkflowDefinition_GetHashCode"></a> GetHashCode\(\)

```csharp
public override int GetHashCode()
```

#### Returns

 [int](https://learn.microsoft.com/dotnet/api/system.int32)

### <a id="Tracon_WorkflowDefinition_ToString"></a> ToString\(\)

```csharp
public override string ToString()
```

#### Returns

 [string](https://learn.microsoft.com/dotnet/api/system.string)

## Operators

### <a id="Tracon_WorkflowDefinition_op_Equality_Tracon_WorkflowDefinition_Tracon_WorkflowDefinition_"></a> operator ==\(WorkflowDefinition?, WorkflowDefinition?\)

```csharp
public static bool operator ==(WorkflowDefinition? left, WorkflowDefinition? right)
```

#### Parameters

`left` [WorkflowDefinition](/api/tracon.workflowdefinition/)?

`right` [WorkflowDefinition](/api/tracon.workflowdefinition/)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)

### <a id="Tracon_WorkflowDefinition_op_Inequality_Tracon_WorkflowDefinition_Tracon_WorkflowDefinition_"></a> operator \!=\(WorkflowDefinition?, WorkflowDefinition?\)

```csharp
public static bool operator !=(WorkflowDefinition? left, WorkflowDefinition? right)
```

#### Parameters

`left` [WorkflowDefinition](/api/tracon.workflowdefinition/)?

`right` [WorkflowDefinition](/api/tracon.workflowdefinition/)?

#### Returns

 [bool](https://learn.microsoft.com/dotnet/api/system.boolean)
