Skip to content
Tracon

WorkflowAgentBinding

Namespace Tracon · Assembly Tracon.Workflows.dll

Binds catalog agents to a workflow graph defined in code.

public static class WorkflowAgentBinding
Inheritance
object ← WorkflowAgentBinding
Inherited Members
object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

Do not put an agent taken from the catalog DIRECTLY into the graph. IAgentCatalog.ResolveAsync returns an agent carrying the run-recording wrapper, but Microsoft Agent Framework calls it with options = null; the wrapper cannot read tree info from the incoming settings and opens its own root row instead. Result: the workflow run looks empty, the agents are independent roots in the list, and the waterfall is drawn wrong. Measured: in the sample app, the tree came back as one row instead of three.

This helper wraps the agent with ChildAgentInvoker. The wrapper reads tree info from the ambient scope, applies the depth/budget/ tenant limits, and attaches the sub-run under the workflow row. For workflows defined from the UI, the compiler does the same wrapping.

tracon.AddWorkflow("summarize-and-translate", services =>
AgentWorkflowBuilder.BuildSequential("summarize-and-translate",
[
services.GetWorkflowAgent("summarize-and-translate", "summarizer"),
services.GetWorkflowAgent("summarize-and-translate", "translator"),
]));

To run an agent as a plain step of a graph with a revision loop or a human approval - a step that takes the messages of the node before it and passes on its answer - use WorkflowAgentBinding.GetWorkflowAgentStep instead.

GetWorkflowAgent(IServiceProvider, string, string, string?)

Section titled “ GetWorkflowAgent(IServiceProvider, string, string, string?)”

Wraps a catalog agent in a form that can be placed in a workflow graph.

public static AIAgent GetWorkflowAgent(this IServiceProvider services, string workflowName, string agentName, string? description = null)

services IServiceProvider

The service provider.

workflowName string

The name of the enclosing workflow. Appears in error messages.

agentName string

The name of the agent to bind.

description string?

A description of what the agent does. In the GroupChat and Magentic patterns it reaches the participant list sent to the model; leaving it empty makes it harder for the manager agent to know when to call whom.

AIAgent

An agent that can be placed in the graph.

The agent is resolved lazily: this call does not read the catalog, it only builds a wrapper. This way, when an agent definition changes, the compiled workflow does not go stale, and the factory being synchronous causes no problem.

The agent is meant to be hosted by a ready-made pattern or an AIAgentBinding: when its tool needs approval, the wrapper passes the request on and the host turns it into a workflow request that waits for a person. Calling the returned agent yourself from a plain function node would drop the request, so a step of that kind binds the agent with WorkflowAgentBinding.GetWorkflowAgentStep instead, which refuses the approval.

The same instance is returned for the same (workflowName, agentName) pair. This is deliberate: Microsoft Agent Framework derives executor ids from the agent instance’s identity, and returning a new instance on every call would make checkpoints incompatible.

ArgumentNullException

services is null.

ArgumentException

One of the names is empty.

GetWorkflowAgentStep(IServiceProvider, string, string)

Section titled “ GetWorkflowAgentStep(IServiceProvider, string, string)”

Binds a catalog agent as a plain step of a workflow graph defined in code - a node that takes the messages of the node before it and passes on the agent’s answer.

public static ExecutorBinding GetWorkflowAgentStep(this IServiceProvider services, string workflowName, string agentName)

services IServiceProvider

The service provider.

workflowName string

The name of the enclosing workflow. Appears in error messages.

agentName string

The name of the agent to run. Also the id of the step.

ExecutorBinding

The executor binding to put in the graph.

Everything the other overload says applies here too; the step runs with no timeout of its own and the agent’s current version.

ArgumentNullException

services is null.

ArgumentException

One of the names is empty.

GetWorkflowAgentStep(IServiceProvider, string, string, Action<WorkflowAgentStepOptions>)

Section titled “ GetWorkflowAgentStep(IServiceProvider, string, string, Action<WorkflowAgentStepOptions>)”

Binds a catalog agent as a plain step of a workflow graph defined in code, with the step’s own timeout and a version pin, fixed or read from a run parameter.

public static ExecutorBinding GetWorkflowAgentStep(this IServiceProvider services, string workflowName, string agentName, Action<WorkflowAgentStepOptions> configure)

services IServiceProvider

The service provider.

workflowName string

The name of the enclosing workflow. Appears in error messages.

agentName string

The name of the agent to run. Also the id of the step.

configure Action<WorkflowAgentStepOptions>

Sets the step’s timeout and version pin or version parameter; called once, here.

ExecutorBinding

The executor binding to put in the graph.

This is not WorkflowAgentBinding.GetWorkflowAgent. That helper returns an agent that a ready-made pattern or an AIAgentBinding hosts; the host runs it only when it is sent a Workflows.TurnToken, and nothing sends one to a node that is not the graph’s entry. A step bound here is a plain function executor: it runs when a message arrives, wherever the edge comes from - a back edge included - so a revision loop works. The price is that it streams no token deltas into the workflow’s event feed and keeps no Microsoft Agent Framework session; a step that revises a draft carries the draft and the feedback in the messages it is given.

The id of the step is the agent’s name, as in a stored chain, so an agent is used once in a graph. The agent runs as a child of the workflow’s run: it records its own run row with the full message and usage history, and the tree’s depth, budget and tenant rules apply. The step does not stream: it asks the agent for its whole answer, so the structured-response repair (Tracon:StructuredResponse) and a loop agent’s final iteration work as they do for a plain agent run.

A version is fixed in the graph or chosen by the run, never both. WorkflowAgentStepOptions.AgentVersion fixes it for every run; WorkflowAgentStepOptions.AgentVersionParameter names a run parameter that carries it. The factory of a graph built in code cannot read the run’s parameters, so the step reads the value each time it runs.

The step takes and passes on a List<ChatMessage>; put a node between it and a node of another type.

tracon.AddWorkflow("review-and-revise", services =>
{
var writer = services.GetWorkflowAgentStep("review-and-revise", "writer", step =>
{
step.Timeout = TimeSpan.FromMinutes(3);
step.AgentVersion = 4;
});
var check = services.GetWorkflowFunction("check");
return new WorkflowBuilder(writer)
.AddEdge(writer, check)
.WithOutputFrom(check)
.WithName("review-and-revise")
.Build();
});

ArgumentNullException

One of the parameters is null.

ArgumentException

One of the names is empty, WorkflowAgentStepOptions.AgentVersionParameter is empty, or both it and WorkflowAgentStepOptions.AgentVersion are set.

ArgumentOutOfRangeException

WorkflowAgentStepOptions.Timeout is outside the range an agent step accepts, or WorkflowAgentStepOptions.AgentVersion is less than 1.