# WorkflowFunctionOptions

> 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.workflowfunctionoptions/
> Summary: WorkflowFunctionOptions: The optional settings of a workflow function registered with AddWorkflowFunction: its description, retry policy, timeout, how many calls may run at once and.

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

The optional settings of a workflow function registered with
`AddWorkflowFunction`: its description, retry policy, timeout, how many calls may run at
once and whether it starts when the call tree's budget is spent.

```csharp
public sealed class WorkflowFunctionOptions
```

<dl class="api-relations"><dt>Inheritance</dt><dd><a href="https://learn.microsoft.com/dotnet/api/system.object">object</a> ← <a href="/api/tracon.workflowfunctionoptions/">WorkflowFunctionOptions</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 callback with properties rather than optional parameters: a public method
that carries optional parameters freezes its signature at the first stable
release, and the next setting would need one more overload - the same
reason `AddTool` takes a [Action](https://learn.microsoft.com/dotnet/api/system.action-1) over its own options type.

## Constructors

### <a id="Tracon_WorkflowFunctionOptions__ctor"></a> WorkflowFunctionOptions\(\)

```csharp
public WorkflowFunctionOptions()
```

## Properties

### <a id="Tracon_WorkflowFunctionOptions_Description"></a> Description

Gets or sets the short description shown in the function catalog.

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

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

Gets or sets how many calls of the function may run at the same time in this process.
[null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) (the default) means no limit of its own: only the run slots
(`Tracon:Workflows:MaxConcurrentRuns`) bound it.

```csharp
public int? MaxConcurrency { get; set; }
```

#### Property Value

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

For a node that is costly to run in parallel: a GPU voice synthesis, a render. The limit
belongs to the function, so it holds across every workflow that uses it and across
every tenant, and it reaches a node of a stored chain and a node of a graph built in code
([WorkflowFunctionBinding.GetWorkflowFunction](/api/tracon.workflowfunctionbinding/)) alike.

A call that finds every slot taken waits. The wait belongs to the run: it ends when the run is
cancelled or reaches its deadline, and it is *not* counted against
[WorkflowFunctionOptions.Timeout](/api/tracon.workflowfunctionoptions/#Tracon_WorkflowFunctionOptions_Timeout), which bounds the node's own work. Each attempt of a retried node takes a
slot of its own and gives it back before the retry's delay, so a node that waits to retry does
not hold a slot. The budget gate ([WorkflowFunctionOptions.StartsWhenBudgetIsSpent](/api/tracon.workflowfunctionoptions/#Tracon_WorkflowFunctionOptions_StartsWhenBudgetIsSpent)) is read after the slot
is taken, because the budget can run out while the call waits.

**The limit is per process.** A host with several replicas allows that many calls
per replica. A handler that ignores its token after a [WorkflowFunctionOptions.Timeout](/api/tracon.workflowfunctionoptions/#Tracon_WorkflowFunctionOptions_Timeout) keeps running
without a slot; pass the token on. A wait writes no run event; it is logged at the
`Debug` level.

Must be 1 or more; another value throws [ArgumentOutOfRangeException](https://learn.microsoft.com/dotnet/api/system.argumentoutofrangeexception) when the
function is registered.

### <a id="Tracon_WorkflowFunctionOptions_RetryPolicy"></a> RetryPolicy

Gets or sets the policy that retries this node on a transient provider error
instead of failing the whole run. [null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) (the default) means
no retry. Every attempt sees the same settings. See
[WorkflowNodeRetryPolicy](/api/tracon.workflownoderetrypolicy/).

```csharp
public WorkflowNodeRetryPolicy? RetryPolicy { get; set; }
```

#### Property Value

 [WorkflowNodeRetryPolicy](/api/tracon.workflownoderetrypolicy/)?

### <a id="Tracon_WorkflowFunctionOptions_StartsWhenBudgetIsSpent"></a> StartsWhenBudgetIsSpent

Gets or sets whether the node starts even when the call tree's cost or time budget, or
the tenant's cost quota, is already spent. [false](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) (the default) refuses it.

```csharp
public bool StartsWhenBudgetIsSpent { get; set; }
```

#### Property Value

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

A function node is refused at its start once `Tracon:AgentGraph:MaxTotalCost` or
`Tracon:AgentGraph:MaxDuration` is passed: the run ends `Failed` with
[TraconRunBudgetExceededException](/api/tracon.traconrunbudgetexceededexception/) (`run_budget_exceeded`) and no later
node runs. A node that is already running is not stopped, and the token budget never
stops a node. A host that sets neither ceiling is not affected.

The ceiling is the logical run's. A run that continues an earlier one (a person's answer, an
operator's resume, a recovery after an interruption) starts from what the earlier runs spent,
and the time they were executing, so a workflow that waits for a person does not get the whole
ceiling again with every answer.

The tenant's quota is read at the same place. Once the tenant's cost quota for the current period
is spent, counting what this run has spent that its counter has not seen yet, the node does not start
either: the run ends `Failed` with [TraconTenantQuotaExceededException](/api/tracon.tracontenantquotaexceededexception/)
(`tenant_quota_exceeded`). The quota resets when its period ends; the budget is a setting.

Set this to [true](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/bool) for a node that spends nothing and should still run
after a costly one: a step that stores the output the budget has just paid for. The
node's own reported spend still counts against the budget and the quota; only its start is exempt.
The exemption is a property of the node's code, so it is set here and cannot be set by
an operator in a workflow definition.

### <a id="Tracon_WorkflowFunctionOptions_Timeout"></a> Timeout

Gets or sets the longest time one call of the function may take.
[null](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) (the default) means no time limit of its own: only the
run's deadline (`Tracon:Workflows:RunTimeout`) stops it.

```csharp
public TimeSpan? Timeout { get; set; }
```

#### Property Value

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

A node can set its own value ([WorkflowNodeReference.Timeout](/api/tracon.workflownodereference/#Tracon_WorkflowNodeReference_Timeout)); the
node's value wins over this one. When the time is up, the token the handler was
given is cancelled, the run stops waiting for the handler, and the run ends
`Failed` with [TraconWorkflowFunctionTimeoutException](/api/tracon.traconworkflowfunctiontimeoutexception/)
(`workflow_function_timeout`). No later node runs.

**Pass the token on.** A handler that ignores its token keeps
running in the background after the run has moved on, and any side effect it
has still happens. What it returns then is discarded; its end is logged.

With a [WorkflowFunctionOptions.RetryPolicy](/api/tracon.workflowfunctionoptions/#Tracon_WorkflowFunctionOptions_RetryPolicy), the timeout applies to each attempt and a
timed-out attempt is retried, so the longest a node can take is about
`MaxAttempts × Timeout` plus the delays between attempts.

Must be from one millisecond to about 49.7 days; another value throws
[ArgumentOutOfRangeException](https://learn.microsoft.com/dotnet/api/system.argumentoutofrangeexception) when the function is registered.
