< Summary

Information
Class: NexusLabs.Needlr.AgentFramework.Context.AgentExecutionContextExtensions
Assembly: NexusLabs.Needlr.AgentFramework
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework/Context/AgentExecutionContextExtensions.cs
Line coverage
100%
Covered lines: 18
Uncovered lines: 0
Coverable lines: 18
Total lines: 91
Line coverage: 100%
Branch coverage
100%
Covered branches: 8
Total branches: 8
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GetWorkspace(...)100%11100%
GetRequiredWorkspace(...)100%22100%
GetProperty(...)100%22100%
GetProperty(...)100%22100%
GetRequired(...)100%22100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework/Context/AgentExecutionContextExtensions.cs

#LineLine coverage
 1namespace NexusLabs.Needlr.AgentFramework.Context;
 2
 3/// <summary>
 4/// Extension methods for <see cref="IAgentExecutionContextAccessor"/> and
 5/// <see cref="IAgentExecutionContext"/>.
 6/// </summary>
 7public static class AgentExecutionContextExtensions
 8{
 9    /// <summary>
 10    /// Gets the workspace from the context, or <see langword="null"/> if none is set.
 11    /// Works with both <see cref="AgentExecutionContext"/> (which stores the workspace
 12    /// in Properties automatically) and custom implementations that put an
 13    /// <see cref="Workspace.IWorkspace"/> in the property bag under the type key.
 14    /// </summary>
 15    public static Workspace.IWorkspace? GetWorkspace(this IAgentExecutionContext context)
 16    {
 617        ArgumentNullException.ThrowIfNull(context);
 618        return context.GetProperty<Workspace.IWorkspace>();
 19    }
 20
 21    /// <summary>
 22    /// Gets the workspace from the context, throwing if none is set. Convenience for
 23    /// tool implementations that require a workspace to operate.
 24    /// </summary>
 25    /// <exception cref="InvalidOperationException">No workspace is available in the current context.</exception>
 26    public static Workspace.IWorkspace GetRequiredWorkspace(this IAgentExecutionContext context)
 27    {
 328        ArgumentNullException.ThrowIfNull(context);
 329        return context.GetWorkspace() ?? throw new InvalidOperationException(
 330            "No workspace is available in the current execution context. " +
 331            "The orchestration layer must provide an IWorkspace when constructing the execution context.");
 32    }
 33
 34    /// <summary>
 35    /// Gets a typed property from the context's property bag, keyed by the type's
 36    /// full name. Returns <see langword="null"/> if not found or if the stored value
 37    /// is not assignable to <typeparamref name="T"/>.
 38    /// </summary>
 39    /// <remarks>
 40    /// <para>
 41    /// The default key (<c>typeof(T).FullName</c>) works well when each property type
 42    /// is unique within a context — the common case for domain records like
 43    /// <c>ArticleAssignment</c>, <c>SeoReport</c>, etc.
 44    /// </para>
 45    /// <para>
 46    /// <see cref="IAgentExecutionContext.Properties"/> is read-only by design.
 47    /// Consumers that need to store typed state should populate the property bag at
 48    /// context construction time via their own <see cref="IAgentExecutionContext"/>
 49    /// implementation.
 50    /// </para>
 51    /// </remarks>
 52    public static T? GetProperty<T>(this IAgentExecutionContext context) where T : class
 53    {
 1154        ArgumentNullException.ThrowIfNull(context);
 1155        return context.Properties.TryGetValue(typeof(T).FullName!, out var value)
 1156            ? value as T
 1157            : null;
 58    }
 59
 60    /// <summary>
 61    /// Gets a typed property from the context's property bag with an explicit key.
 62    /// Returns <see langword="null"/> if not found or if the stored value is not
 63    /// assignable to <typeparamref name="T"/>.
 64    /// </summary>
 65    public static T? GetProperty<T>(this IAgentExecutionContext context, string key) where T : class
 66    {
 367        ArgumentNullException.ThrowIfNull(context);
 368        return context.Properties.TryGetValue(key, out var value)
 369            ? value as T
 370            : null;
 71    }
 72
 73    /// <summary>
 74    /// Returns the current <see cref="IAgentExecutionContext"/> or throws if none is established.
 75    /// Tools should call this rather than checking <see cref="IAgentExecutionContextAccessor.Current"/>
 76    /// directly — there is no valid "anonymous" execution.
 77    /// </summary>
 78    /// <exception cref="InvalidOperationException">
 79    /// Thrown when no execution context scope is active. This indicates a programming error:
 80    /// the orchestration layer must call <see cref="IAgentExecutionContextAccessor.BeginScope"/>
 81    /// before invoking tools.
 82    /// </exception>
 83    public static IAgentExecutionContext GetRequired(this IAgentExecutionContextAccessor accessor)
 84    {
 385        ArgumentNullException.ThrowIfNull(accessor);
 86
 287        return accessor.Current ?? throw new InvalidOperationException(
 288            "Tool invoked outside an agent execution scope. " +
 289            "The orchestration layer must call IAgentExecutionContextAccessor.BeginScope(context) before invoking tools.
 90    }
 91}