Universal.Operative.Sdk 6.1.3

dotnet add package Universal.Operative.Sdk --version 6.1.3
                    
NuGet\Install-Package Universal.Operative.Sdk -Version 6.1.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Universal.Operative.Sdk" Version="6.1.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Universal.Operative.Sdk" Version="6.1.3" />
                    
Directory.Packages.props
<PackageReference Include="Universal.Operative.Sdk" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Universal.Operative.Sdk --version 6.1.3
                    
#r "nuget: Universal.Operative.Sdk, 6.1.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Universal.Operative.Sdk@6.1.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Universal.Operative.Sdk&version=6.1.3
                    
Install as a Cake Addin
#tool nuget:?package=Universal.Operative.Sdk&version=6.1.3
                    
Install as a Cake Tool

About

Universal.Operative.Sdk is the shared kernel for the Universal.Operative.Sdk family: the provider-neutral content model (Block and its subtypes, Source, Citation), the tool-calling contract (ITool, Tool<TArgs>, ToolResult, ToolDefinition, ToolChoice), the canonical dispatch boundary (ToolCallDispatcher, IToolCallHook), token accounting (Usage, ITokenEstimator), and cross-cutting infrastructure (IDiagnosticSink). It also ships a baseline tool set (Read, Write, Edit, Glob, Grep, a shell, and TodoWrite) and an alternate coding set (Read, Glob, Grep, shell, apply_patch, and update_plan).

None of this assumes a particular execution model — it's reused unchanged by both Universal.Operative.Sdk.Discrete (turn-based: Conversation, Engine, Operative) and Universal.Operative.Sdk.Realtime (live duplex sessions). Install this package alongside whichever of those two matches what you're building; you won't normally install it alone.

How to Use

Installation

dotnet add package Universal.Operative.Sdk
dotnet add package Universal.Operative.Sdk.Discrete   # turn-based agents
# or
dotnet add package Universal.Operative.Sdk.Realtime   # duplex-stream / voice agents

Core concepts

  • Block — the provider-neutral content unit (TextBlock, ImageBlock, AudioBlock, DocumentBlock, VideoBlock, ToolCallBlock, ToolResultBlock, ReasoningBlock, RefusalBlock, ServerToolUseBlock/ServerToolResultBlock, RawJsonBlock). Both execution models build their message/event shapes out of these. Source (Base64Source, UrlSource, FileIdSource, TextSource, ContentSource) backs any media-bearing block; Citation (DocumentCitation, UrlCitation) attaches source attribution to a TextBlock.
  • ITool / Tool<TArgs> — a callable the model can invoke. Subclass Tool<TArgs> with a typed argument record and a Definition whose Parameters schema is generated straight from that record via BuildParametersSchema(), so the schema the model sees and the type ExecuteAsync deserializes into can't drift apart; the base class handles (de)serialization and turns malformed arguments into a model-readable error instead of an exception. See Tools/BaselineToolSet.cs and Tools/FileSystem/GlobTool.cs for worked examples.
  • ToolResult — a tool's output: a Block list plus IsError. Factories Text, Json<T>, Image; implicit conversions from string/Block.
  • ToolDefinition — a tool's name, description, and JSON Schema parameters, as sent to a provider; ToolChoice (Auto/Required/None/Tool) controls whether/which tool the model must call.
  • Usage — token accounting (InputTokens, OutputTokens, provider-specific Extensions), reused by both a turn-based Message.Usage and a realtime session's usage events. ITokenEstimator (default: CharHeuristicTokenEstimator) estimates the token footprint of a Block/text for budget-aware transformers.
  • IDiagnosticSink — a seam for the SDK to surface internal notices (a dropped stream block, an abandoned tool call) without taking a dependency on any particular logging library.

Tool dispatch hooks

ToolCallDispatcher is the provider-neutral execution boundary shared by turn-based engines, callback-driven adapters, and realtime sessions. It enforces the exact per-model-call tool allowlist, runs before/after hooks, routes requested background work, applies tool-specific/default/capped timeouts, and reports abandoned faults through IDiagnosticSink. Scheduling, concurrency gates, and lifecycle events remain owned by the caller.

A before hook may rewrite ToolCallExecution.Call or set Result to veto execution; an after hook may inspect or replace a completed result. IToolCallHookContext.Scope provides state shared by calls in the same host-defined scope. Setting ToolCallExecution.TurnTerminationReason asks a turn-based host to stop after recording the call result.

public sealed class AuditHook : IToolCallHook
{
    public Task<ToolCallHookResult?> InvokeAsync(
        IToolCallHookContext context,
        CancellationToken cancellationToken = default)
    {
        Console.WriteLine($"{context.Stage}: {context.Execution.Call.Name}");
        return Task.FromResult<ToolCallHookResult?>(null);
    }
}

In version 6 these contracts live in Universal.Operative.Sdk, not Universal.Operative.Sdk.Discrete, because they apply equally to discrete and realtime execution.

Writing a custom tool

using System.ComponentModel;
using System.Text.Json.Serialization;
using Universal.Operative.Sdk.Tools;

public sealed class WeatherTool : Tool<WeatherTool.Args>
{
    public override string Name => "get_weather";
    public override bool IsConcurrencySafe => true;

    public override ToolDefinition Definition { get; } = new()
    {
        Name = "get_weather",
        Description = "Get the current weather for a city.",
        Parameters = BuildParametersSchema(),
    };

    public sealed record Args
    {
        [JsonPropertyName("city")]
        [Description("The city to get the weather for.")]
        public required string City { get; init; }
    }

    protected override async Task<ToolResult> ExecuteAsync(Args args, CancellationToken cancellationToken)
        => ToolResult.Json(new { city = args.City, tempF = 72 });
}

BuildParametersSchema() reflects over Args: [JsonPropertyName] controls each parameter's wire name, [Description] becomes the text the model sees for it, and required string/[Required] marks it mandatory. Use a real C# enum (not a loosely-typed string) for any parameter with a closed set of valid values. Parameters is a Universal.Common.Json.JsonSchema, so a hand-authored schema still works when reflection can't express the shape you need (e.g. oneOf/$ref). IsConcurrencySafe = true marks a read-only tool as safe to run in parallel with other calls in the same turn/session; mutating tools default to false.

A tool whose work can outlive a single call implements IBackgroundTool (most conveniently via BackgroundTool<TArgs>) — see ShellTool for a worked example.

Model-oriented tool sets

CodingToolSet.Create() returns portable implementations of Read, Glob, Grep, shell, apply_patch, and update_plan. Every provider can expose them as ordinary function tools. Adapters may recognize their semantic ToolDefinition.Kind and promote them to native tools.

using Universal.Operative.Sdk.Tools.Coding;

IReadOnlyList<ITool> tools = CodingToolSet.Create(new CodingToolSet.Options
{
    WorkingDirectory = workspace,
});

HTTP proxy tools

A tool that just calls an external REST API can subclass HttpProxyTool<TArgs> instead of hand-rolling ExecuteAsync — it owns the build → send → format template; a subclass overrides BuildRequestAsync and, optionally, FormatResponseAsync. HttpClientProxyTool<TArgs> is the plain-HttpClient implementation. Pair this with Universal.Operative.Sdk.Http's HttpServiceClientProxyTool<TServiceClient, TArgs> when the target API already has a Universal.Common.Net.Http.HttpServiceClient.

References

ReferenceTool fetches whatever content a reference URI points to, via a registered IReferenceResolver (InMemoryReferenceResolver is the built-in default). It's deliberately generic — the tool carries no opinion about what a reference is; it only resolves a URI to IReadOnlyList<Block> content.

Capability catalogs

When an application owns more tools than it wants to publish on every model request, group related tools into immutable capability packs:

using Universal.Operative.Sdk.Tools;

ToolPack documents = new(
    new ToolPackDescriptor
    {
        Id = "documents",
        Name = "Documents",
        Description = "Creates, edits, and renders documents.",
        Aliases = ["word document", "report"],
        Actions = ["create", "edit", "render"],
        FileExtensions = [".docx"],
    },
    [inspectTool, editTool, renderTool]);

ToolCatalog catalog = new([documents, presentations]);

IToolPackResolver is the policy seam that selects relevant packs. LexicalToolPackResolver is the deterministic built-in implementation; applications can replace it with semantic search, authorization-aware routing, or another strategy.

A compact catalog summary can tell a model which capabilities may be discovered without including every full tool schema:

IToolCatalogSummarizer summarizer = new ConciseToolCatalogSummarizer();

string capabilitySummary = await summarizer.SummarizeAsync(
    new ToolCatalogSummaryRequest
    {
        Catalog = catalog,
        MaximumCharacters = 2_000,
    });

The built-in summary lists pack names, stable identifiers, and truncated descriptions in registration order. Implement IToolCatalogSummarizer for a different token budget, localization, permission-aware redaction, or grouping. Summarization is intentionally separate from resolution and prompt composition: the host decides where and when the summary belongs in its model instructions.

License

Free for noncommercial use under the Universal.Operative Noncommercial License. Source is closed; commercial use requires a separate license from Andrew Ong.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (35)

Showing the top 5 NuGet packages that depend on Universal.Operative.Sdk:

Package Downloads
Universal.Operative.Sdk.Discrete

Turn-based agent runtime for Universal.Operative.Sdk: Conversation/Message, IModel, Engine, and Operative.

Universal.Operative.Sdk.Tavily

Tavily-backed web search and web fetch tools for the Universal.Operative.Sdk.

Universal.Operative.Sdk.Discrete.OpenAI

OpenAI Chat Completions and Responses API adapters for Universal.Operative.Sdk.Discrete.

Universal.Operative.Sdk.Discrete.Anthropic

Anthropic Messages API adapter for Universal.Operative.Sdk.Discrete.

Universal.Operative.Sdk.Discrete.Anthropic.ClaudeAgentSdk

Claude Agent SDK model adapter for Universal.Operative.Sdk.Discrete.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
6.1.3 558 10/2/2026
6.1.2 1,170 9/7/2026
6.1.1 142 9/5/2026
6.0.3 330 9/4/2026
6.0.2 302 9/3/2026
6.0.1 328 9/2/2026
6.0.0 868 9/1/2026
5.2.0 778 8/26/2026
5.1.1 125 8/25/2026
5.1.0 289 8/24/2026
5.0.1 546 8/19/2026
5.0.0 422 8/12/2026
4.2.0 262 8/5/2026
4.1.3 136 8/4/2026
4.1.2 148 7/31/2026
4.1.1 141 7/31/2026
4.1.0 220 7/30/2026
4.0.0 371 7/28/2026
3.3.0 146 7/28/2026
3.2.0 369 7/27/2026
Loading failed

Preserve tool kinds and provider extension metadata when renaming tools.