Skip to content

IterativeLoopStageExecutor

NexusLabs.Needlr.AgentFramework.Workflows

NexusLabs.Needlr.AgentFramework.Workflows.Sequential

IterativeLoopStageExecutor Class

Executes a pipeline stage by running an NexusLabs.Needlr.AgentFramework.Iterative.IIterativeAgentLoop with dynamically constructed options and context.

public sealed class IterativeLoopStageExecutor : NexusLabs.Needlr.AgentFramework.Workflows.Sequential.IStageExecutor

Inheritance System.Object 🡒 IterativeLoopStageExecutor

Implements IStageExecutor

Example

// Basic usage
var executor = new IterativeLoopStageExecutor(
    iterativeLoop,
    ctx => new IterativeLoopOptions
    {
        Instructions = "Write an article.",
        Tools = tools,
        PromptFactory = iterCtx => BuildPrompt(iterCtx.Workspace),
        MaxIterations = 15,
        LoopName = ctx.StageName,
    });

// With onLoopCompleted to override the framework-mapped termination
var executor = new IterativeLoopStageExecutor(
    iterativeLoop,
    ctx => buildOptions(ctx),
    onLoopCompleted: (loopResult, ctx) =>
    {
        accessor.LastDiagnostics = loopResult.Diagnostics;
        // Return a Custom termination to attach app narrative + metadata.
        return new StageTermination.Custom(
            Reason: "Reconciled",
            Properties: new Dictionary<string, object?> { ["FindingCount"] = 7 });
    });

// With shouldTreatAsSuccess for acceptable non-success terminations
var executor = new IterativeLoopStageExecutor(
    iterativeLoop,
    ctx => buildOptions(ctx),
    shouldTreatAsSuccess: r =>
        r.Termination is TerminationReason.MaxIterationsReached
                      or TerminationReason.MaxToolCallsReached);

// Composing with decorators
var timedExecutor = new TimeoutExecutor(
    new IterativeLoopStageExecutor(loop, optionsFactory),
    TimeSpan.FromMinutes(10));

Remarks

This executor bridges the workspace-driven iterative loop pattern into the IStageExecutor contract used by SequentialPipelineRunner. Unlike AgentStageExecutor (which wraps a single-pass AIAgent.RunAsync call), this executor runs a multi-iteration loop where each iteration builds a fresh prompt from workspace state, maintaining O(n) token cost.

All termination paths use result-based signaling — the executor never throws exceptions for loop-level failures. This means exception-driven decorators like ContinueOnFailureExecutor and FallbackExecutor do not intercept loop termination results. For advisory behavior, set failureDisposition to ContinueAdvisory. For timeout enforcement, TimeoutExecutor still works because the loop observes the linked System.Threading.CancellationToken and terminates cooperatively.

On every successful loop completion, the executor maps NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopResult.Termination (a NexusLabs.Needlr.AgentFramework.Iterative.TerminationReason enum) to a typed NexusLabs.Needlr.AgentFramework.Diagnostics.StageTermination case and surfaces it via Termination. The onLoopCompleted callback can return a NexusLabs.Needlr.AgentFramework.Diagnostics.StageTermination to override the framework-mapped default (e.g. to attach app-specific narrative as a NexusLabs.Needlr.AgentFramework.Diagnostics.StageTermination.Custom case); returning null uses the framework default.

Constructors

IterativeLoopStageExecutor(IIterativeAgentLoop, Func<StageExecutionContext,IterativeLoopOptions>, Func<StageExecutionContext,IterativeContext>, Func<IterativeLoopResult,StageExecutionContext,StageTermination>, Func<IterativeLoopResult,bool>, FailureDisposition) Constructor

Initializes a new IterativeLoopStageExecutor.

public IterativeLoopStageExecutor(NexusLabs.Needlr.AgentFramework.Iterative.IIterativeAgentLoop loop, System.Func<NexusLabs.Needlr.AgentFramework.Workflows.Sequential.StageExecutionContext,NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopOptions> optionsFactory, System.Func<NexusLabs.Needlr.AgentFramework.Workflows.Sequential.StageExecutionContext,NexusLabs.Needlr.AgentFramework.Iterative.IterativeContext>? contextFactory=null, System.Func<NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopResult,NexusLabs.Needlr.AgentFramework.Workflows.Sequential.StageExecutionContext,NexusLabs.Needlr.AgentFramework.Diagnostics.StageTermination?>? onLoopCompleted=null, System.Func<NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopResult,bool>? shouldTreatAsSuccess=null, NexusLabs.Needlr.AgentFramework.Workflows.Sequential.FailureDisposition failureDisposition=NexusLabs.Needlr.AgentFramework.Workflows.Sequential.FailureDisposition.AbortPipeline);

Parameters

loop NexusLabs.Needlr.AgentFramework.Iterative.IIterativeAgentLoop

The iterative agent loop to execute.

optionsFactory System.Func<StageExecutionContext,NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopOptions>

Factory that produces the NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopOptions from the current stage context. Called once per execution — callers configure instructions, tools, prompt factory, iteration limits, and all other loop settings here.

contextFactory System.Func<StageExecutionContext,NexusLabs.Needlr.AgentFramework.Iterative.IterativeContext>

Optional factory that produces the NexusLabs.Needlr.AgentFramework.Iterative.IterativeContext from the current stage context. When null (the default), the executor creates an NexusLabs.Needlr.AgentFramework.Iterative.IterativeContext using Workspace. Provide a factory to pre-populate NexusLabs.Needlr.AgentFramework.Iterative.IterativeContext.State or use a different workspace.

onLoopCompleted System.Func<NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopResult,StageExecutionContext,NexusLabs.Needlr.AgentFramework.Diagnostics.StageTermination>

Optional callback invoked immediately after the loop completes, before result mapping. Receives the raw NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopResult and the StageExecutionContext. May return a NexusLabs.Needlr.AgentFramework.Diagnostics.StageTermination to override the framework-mapped default (e.g. to attach app narrative as a NexusLabs.Needlr.AgentFramework.Diagnostics.StageTermination.Custom case); returning null uses the framework default mapped from NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopResult.Termination. Called on both success and failure paths. Not called if the loop throws an exception.

shouldTreatAsSuccess System.Func<NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopResult,System.Boolean>

Optional predicate evaluated when the loop result has NexusLabs.Needlr.AgentFramework.Iterative.IterativeLoopResult.Succeeded = false. When the predicate returns true, the executor treats the result as a success. Use this for termination reasons like NexusLabs.Needlr.AgentFramework.Iterative.TerminationReason.MaxIterationsReached that are acceptable in the caller's domain. The reported Termination still reflects the loop's actual termination — only the success/failure outcome is flipped. Not called when the loop already succeeded.

failureDisposition FailureDisposition

The FailureDisposition applied to failed results. Defaults to AbortPipeline. Set to ContinueAdvisory for stages whose failure should not halt the pipeline.

Methods

IterativeLoopStageExecutor.ExecuteAsync(StageExecutionContext, CancellationToken) Method

Executes the stage logic and returns a result indicating success or failure.

public System.Threading.Tasks.Task<NexusLabs.Needlr.AgentFramework.Workflows.Sequential.StageExecutionResult> ExecuteAsync(NexusLabs.Needlr.AgentFramework.Workflows.Sequential.StageExecutionContext context, System.Threading.CancellationToken cancellationToken);

Parameters

context StageExecutionContext

The execution context providing access to shared pipeline state.

cancellationToken System.Threading.CancellationToken

Token to observe for cancellation.

Implements ExecuteAsync(StageExecutionContext, CancellationToken)

Returns

System.Threading.Tasks.Task<StageExecutionResult>
A StageExecutionResult describing the outcome.