WorkflowsDefining workflows
WORKFLOWS

Defining workflows

Register distinct agent types and connect them with a Flow definition.

This example summarizes text and reviews the summary. Distinct agent types let the runtime resolve each step unambiguously.

Create the host

Install Runiq.AI.Core, Runiq.AI.Agents, and Runiq.AI.Workflows. Supply OpenAI:ApiKey through host configuration and choose a model available to your account.

Program.cs
using Runiq.AI.Agents;
using Runiq.AI.Core;
using Runiq.AI.Workflows;
using Runiq.AI.Workflows.Domain;

var builder = WebApplication.CreateBuilder(args);
var apiKey = builder.Configuration["OpenAI:ApiKey"]
    ?? throw new InvalidOperationException("OpenAI:ApiKey is required.");

builder.Services.AddRuniqServer(options =>
{
    options.AddAgent(new SummaryAgent(apiKey));
    options.AddAgent(new ReviewAgent(apiKey));
});

var flow = new Flow("summary-review", "Summary and review")
    .Step<SummaryAgent>("summarize")
        .OnSuccess("review")
        .OnFailureStop()
    .Step<ReviewAgent>("review")
        .OnSuccessEnd()
        .OnFailureStop()
    .Build();

builder.Services.AddRuniqWorkflows(options => options.AddFlow(flow));

var app = builder.Build();
app.Run();

/// <summary>Summarizes the supplied text.</summary>
public sealed class SummaryAgent : Agent
{
    /// <summary>Creates a summary agent with the configured key.</summary>
    public SummaryAgent(string apiKey)
        : base(id: "summary", name: "Summary",
            instructions: "Summarize the supplied text. Preserve its key facts.",
            model: "openai/gpt-4.1-mini", apiKey: apiKey) { }
}

/// <summary>Reviews a supplied summary.</summary>
public sealed class ReviewAgent : Agent
{
    /// <summary>Creates a review agent with the configured key.</summary>
    public ReviewAgent(string apiKey)
        : base(id: "review", name: "Review",
            instructions: "Improve the clarity of the supplied summary. Do not add facts.",
            model: "openai/gpt-4.1-mini", apiKey: apiKey) { }
}

Registration does not execute the flow. Add the handler from Running workflows before app.Run().

Keep types distinct

Step<TAgent> resolves the exact CLR type. Two plain Agent instances with different IDs still share a type. Use distinct subclasses and register one instance per type.

The resolver builds a type-keyed dictionary of the registered agent collection. Duplicate CLR types can prevent workflow resolution even when IDs differ.

Declare transitions

Execution starts at the first declared step. OnSuccess("review") selects the next step by ID; declaring a second step alone does not make it execute.

Without a success target, success ends the flow. Failure stops by default.

Validate the definition

Build() returns the definition. Before execution, the runner checks for an empty flow, duplicate step IDs, and unknown targets.

Validation does not reject cycles or check every runtime dependency. Keep this flow acyclic and verify agent registrations.

Continue with Host application.

On this page