| | | 1 | | using NexusLabs.Needlr.AgentFramework.Workspace; |
| | | 2 | | |
| | | 3 | | namespace NexusLabs.Needlr.AgentFramework.Workflows.Sequential; |
| | | 4 | | |
| | | 5 | | /// <summary> |
| | | 6 | | /// Provides typed access to pipeline state during phase lifecycle hooks |
| | | 7 | | /// (<see cref="PipelinePhasePolicy.OnEnterAsync"/> and |
| | | 8 | | /// <see cref="PipelinePhasePolicy.OnExitAsync"/>). |
| | | 9 | | /// </summary> |
| | | 10 | | /// <param name="PhaseName">Human-readable name of the current phase.</param> |
| | | 11 | | /// <param name="PhaseIndex">Zero-based index of the current phase in the pipeline.</param> |
| | | 12 | | /// <param name="TotalPhases">Total number of phases in the pipeline.</param> |
| | | 13 | | /// <param name="Workspace">The shared workspace for the pipeline.</param> |
| | | 14 | | /// <param name="PipelineState"> |
| | | 15 | | /// Optional shared state object passed to all phases. Use |
| | | 16 | | /// <see cref="GetRequiredState{T}"/> for type-safe access. |
| | | 17 | | /// </param> |
| | | 18 | | /// <example> |
| | | 19 | | /// <code> |
| | | 20 | | /// var policy = new PipelinePhasePolicy |
| | | 21 | | /// { |
| | | 22 | | /// OnEnterAsync = (ctx, ct) => |
| | | 23 | | /// { |
| | | 24 | | /// var state = ctx.GetRequiredState<MyPipelineState>(); |
| | | 25 | | /// Console.WriteLine($"Phase {ctx.PhaseIndex + 1}/{ctx.TotalPhases}: {ctx.PhaseName}"); |
| | | 26 | | /// return ValueTask.CompletedTask; |
| | | 27 | | /// }, |
| | | 28 | | /// }; |
| | | 29 | | /// </code> |
| | | 30 | | /// </example> |
| | 43 | 31 | | public sealed record PhaseContext( |
| | 1 | 32 | | string PhaseName, |
| | 1 | 33 | | int PhaseIndex, |
| | 1 | 34 | | int TotalPhases, |
| | 1 | 35 | | IWorkspace Workspace, |
| | 44 | 36 | | object? PipelineState = null) |
| | | 37 | | { |
| | | 38 | | /// <summary> |
| | | 39 | | /// Gets the typed pipeline state, or throws if no state was provided or the type doesn't match. |
| | | 40 | | /// </summary> |
| | | 41 | | /// <typeparam name="T">The expected pipeline state type.</typeparam> |
| | | 42 | | /// <returns>The pipeline state cast to <typeparamref name="T"/>.</returns> |
| | | 43 | | /// <exception cref="InvalidOperationException"> |
| | | 44 | | /// Thrown when <see cref="PipelineState"/> is <see langword="null"/> or not of type <typeparamref name="T"/>. |
| | | 45 | | /// </exception> |
| | | 46 | | public T GetRequiredState<T>() where T : class => |
| | 1 | 47 | | PipelineState as T ?? throw new InvalidOperationException( |
| | 1 | 48 | | $"Pipeline state is not available or is not of type {typeof(T).Name}."); |
| | | 49 | | } |