DirectivSys.Sdk 1.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package DirectivSys.Sdk --version 1.1.0
                    
NuGet\Install-Package DirectivSys.Sdk -Version 1.1.0
                    
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="DirectivSys.Sdk" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DirectivSys.Sdk" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="DirectivSys.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 DirectivSys.Sdk --version 1.1.0
                    
#r "nuget: DirectivSys.Sdk, 1.1.0"
                    
#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 DirectivSys.Sdk@1.1.0
                    
#: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=DirectivSys.Sdk&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=DirectivSys.Sdk&version=1.1.0
                    
Install as a Cake Tool

DirectivSys.Sdk

Official .NET SDK for DirectivSys Analytics Platform. Enables seamless integration with DirectivSys to receive AI-powered business intelligence directives and submit analytics payloads.

NuGet License: MIT

Features

Zero Boilerplate - Automatic webhook endpoint creation
🔒 Secure by Default - Built-in authentication and validation
📦 Strongly Typed - Complete DTOs for all analytics types
🚀 Easy Submission - Fluent API for submitting analytics payloads
Async/Await - Modern async patterns throughout

Installation

dotnet add package DirectivSys.Sdk

Or via Package Manager Console:

Install-Package DirectivSys.Sdk

Quick Start

1. Configure Services (Program.cs or Startup.cs)

using DirectivSys.Sdk.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add DirectivSys SDK
builder.Services.AddDirectivSys(options =>
{
    options.ApiKey = "your-directivsys-api-key";
    options.BaseUrl = "https://api.directivsys.com";
    // ClientId is automatically extracted from the API Key
});

var app = builder.Build();

// Map the webhook endpoint
app.MapDirectivWebhook();

// Set up your callback to handle incoming directives
var directivSys = app.GetDirectivSys();
directivSys.OnDirectiveReceived = HandleDirective;

app.Run();

void HandleDirective(GlobalRecord record)
{
    Console.WriteLine($"Received {record.Directives.Count} directives for {record.AnalyticsType}");
    
    foreach (var directive in record.Directives.OrderBy(d => d.Priority))
    {
        Console.WriteLine($"[Priority {directive.Priority}] {directive.Action}");
        Console.WriteLine($"  Rationale: {directive.Rationale}");
        
        // Execute your business logic based on the directive
        switch (directive.Action)
        {
            case "reorderSupplier":
                var sku = directive.Parameters["sku"].ToString();
                var quantity = Convert.ToInt32(directive.Parameters["quantity"]);
                // Your reorder logic here
                break;
                
            case "launchPromotion":
                var targets = directive.Targets;
                // Your promotion logic here
                break;
        }
    }
}

2. Submit Analytics Data

using DirectivSys.Sdk.Models.Payloads;
using DirectivSys.Sdk.Services;

public class InventoryService
{
    private readonly DirectivSysClient _client;

    public InventoryService(DirectivSysClient client)
    {
        _client = client;
    }

    public async Task AnalyzeInventoryAsync()
    {
        var payload = new InventoryHealthPayload
        {
            Sku = "SKU123",
            StockLevel = 20,
            ReorderPoint = 50,
            SafetyStock = 30,
            ForecastedDemandNext30Days = 200,
            AverageLeadTimeDays = 5
        };

        // Submit the payload for async processing
        // Instructions are pre-configured in AnalyticsConfig on the backend
        var response = await _client.SubmitInventoryHealthAsync(payload);
        Console.WriteLine($"Payload submitted: {response.PayloadId}, Status: {response.Status}");
        
        // Option 1: Poll for results
        var result = await PollForResultAsync(response.PayloadId);
        
        // Option 2: Process immediately (synchronous)
        // var result = await _client.ProcessLatestAsync("InventoryHealth");
    }
    
    private async Task<AnalyticsResult?> PollForResultAsync(Guid payloadId, int maxAttempts = 30)
    {
        for (int i = 0; i < maxAttempts; i++)
        {
            var response = await _client.GetResultByPayloadIdAsync(payloadId);
            
            if (response.IsComplete && response.Result != null)
            {
                return response.Result;
            }
            
            if (response.Status == "failed")
            {
                throw new Exception($"Processing failed: {response.Error}");
            }
            
            await Task.Delay(1000); // Wait 1 second before next poll
        }
        
        throw new TimeoutException("Polling timed out");
    }
}

Supported Analytics Types

The SDK includes strongly-typed payload classes for all DirectivSys analytics types:

Important: Instructions for each analytics type are configured once in the AnalyticsConfig on the backend, not sent with each payload submission. Payloads contain only data - this reduces payload size and allows updating instructions without changing client code.

Supply Chain Analytics

  • InventoryHealth - Stock level monitoring and reorder recommendations
  • SupplierReliability - Supplier performance evaluation
  • DemandForecast - Future demand prediction
  • CostOptimization - Order quantity and cost optimization

E-Commerce Analytics

  • CustomerSegmentation - Customer grouping by behavior and value
  • CartAbandonment - Abandoned cart detection and recovery
  • SalesFunnelConversion - Conversion rate tracking and optimization
  • ProductPerformance - Bestseller and slow-mover identification
  • CustomerLifetimeValue - Long-term customer value estimation
  • MarketingROI - Campaign effectiveness measurement

API Reference

Configuration

DirectivSysOptions
public class DirectivSysOptions
{
    public string ApiKey { get; set; }        // Required: Your DirectivSys API Key (X-API-Key header)
    public string BaseUrl { get; set; }       // Default: "https://api.directivsys.com"
    public Guid? ClientId { get; set; }       // Optional: Extracted from API Key if not provided
    public int TimeoutSeconds { get; set; }   // Default: 30
}

Core Models

GlobalRecord

The main container for analytics results received via webhook:

public class GlobalRecord
{
    public Guid RecordId { get; set; }
    public Guid ClientId { get; set; }
    public string AnalyticsType { get; set; }
    public List<Directive> Directives { get; set; }
    public List<Metric> Metrics { get; set; }
    public List<Observation> Observations { get; set; }
    public Provenance Provenance { get; set; }
    public DateTime CreatedAt { get; set; }
}
Directive

Actionable recommendations from the AI agent:

public class Directive
{
    public Guid DirectiveId { get; set; }
    public int Priority { get; set; }                    // 1 = highest priority
    public string Action { get; set; }                   // e.g., "reorderSupplier"
    public Dictionary<string, object> Parameters { get; set; }
    public List<string> Targets { get; set; }
    public string Rationale { get; set; }
    public string Status { get; set; }
}
Metric

Calculated business metrics:

public class Metric
{
    public string Name { get; set; }
    public double Value { get; set; }
    public string Unit { get; set; }
    public string Status { get; set; }      // "healthy", "warning", "critical"
    public string Explanation { get; set; }
}
Observation

Human-readable explanations and context:

public class Observation
{
    public string Text { get; set; }
    public string Severity { get; set; }    // "info", "warning", "critical"
    public string Scope { get; set; }       // "global", "product", "supplier"
}

DirectivSysClient Methods

Submit Analytics Payloads
// Specific analytics types - Submit for async processing
Task<IngestResponse> SubmitInventoryHealthAsync(InventoryHealthPayload payload, CancellationToken cancellationToken = default)
Task<IngestResponse> SubmitCustomerSegmentationAsync(CustomerSegmentationPayload payload, CancellationToken cancellationToken = default)
Task<IngestResponse> SubmitCartAbandonmentAsync(CartAbandonmentPayload payload, CancellationToken cancellationToken = default)
Task<IngestResponse> SubmitProductPerformanceAsync(ProductPerformancePayload payload, CancellationToken cancellationToken = default)

// Generic submission for any analytics type
Task<IngestResponse> SubmitAnalyticsAsync<T>(string analyticsType, T payload, CancellationToken cancellationToken = default) 
    where T : AnalyticsPayloadBase
Process and Retrieve Results
// Process the latest pending payload synchronously
Task<AnalyticsResult> ProcessLatestAsync(string analyticsType, CancellationToken cancellationToken = default)

// Get result for a specific payload (for polling after async submission)
Task<PayloadResultResponse> GetResultByPayloadIdAsync(Guid payloadId, CancellationToken cancellationToken = default)
Response Models
// Response from ingestion
public class IngestResponse
{
    public Guid PayloadId { get; set; }
    public string Status { get; set; }  // "pending"
}

// Complete analytics result
public class AnalyticsResult
{
    public Guid ResultId { get; set; }
    public Guid PayloadId { get; set; }
    public string AnalyticsType { get; set; }
    public DateTime CreatedAt { get; set; }
    public string InputsSummary { get; set; }
    public string InstructionSet { get; set; }
    public string Provenance { get; set; }
    public List<MetricResult> Metrics { get; set; }
    public List<DirectiveResult> Directives { get; set; }
    public List<ObservationResult> Observations { get; set; }
}

// Polling response (can be complete or status)
public class PayloadResultResponse
{
    public bool IsComplete { get; set; }
    public AnalyticsResult? Result { get; set; }  // Available when IsComplete = true
    public string? Status { get; set; }            // "pending", "processing", "failed"
    public string? Error { get; set; }             // Available when Status = "failed"
}

Advanced Usage

Processing Patterns

The SDK supports three different processing patterns:

Pattern 1: Fire-and-Forget Ingestion

Submit payloads for async processing without waiting for results:

var response = await client.SubmitInventoryHealthAsync(payload);
// Store response.PayloadId for later retrieval if needed
Console.WriteLine($"Submitted: {response.PayloadId}");
Pattern 2: Synchronous Processing

Process immediately and get results:

// First ingest the payload
var ingestResponse = await client.SubmitInventoryHealthAsync(payload);

// Then immediately process the latest one
var result = await client.ProcessLatestAsync("InventoryHealth");

// Work with the result
foreach (var directive in result.Directives)
{
    Console.WriteLine($"{directive.Action}: {directive.Rationale}");
}
Pattern 3: Async with Polling

Submit for async processing and poll until complete:

var ingestResponse = await client.SubmitInventoryHealthAsync(payload);

// Poll for results
AnalyticsResult? result = null;
int attempts = 0;
while (result == null && attempts < 30)
{
    await Task.Delay(1000); // Wait 1 second
    
    var response = await client.GetResultByPayloadIdAsync(ingestResponse.PayloadId);
    
    if (response.IsComplete)
    {
        result = response.Result;
    }
    else if (response.Status == "failed")
    {
        throw new Exception($"Processing failed: {response.Error}");
    }
    
    attempts++;
}

Custom Analytics Types

For analytics types not included in the SDK, use the generic submission method:

public class CustomAnalyticsPayload : AnalyticsPayloadBase
{
    public string CustomField1 { get; set; }
    public int CustomField2 { get; set; }
}

var payload = new CustomAnalyticsPayload
{
    CustomField1 = "value",
    CustomField2 = 42
};

await client.SubmitAnalyticsAsync("CustomAnalyticsType", payload);

Accessing Services Directly

// In a controller or service
public class MyController : ControllerBase
{
    private readonly DirectivSysClient _client;
    private readonly IDirectivSysService _service;

    public MyController(DirectivSysClient client, IDirectivSysService service)
    {
        _client = client;
        _service = service;
        
        // Set callback dynamically
        _service.OnDirectiveReceived = HandleDirective;
    }
}

Error Handling

try
{
    var response = await client.SubmitInventoryHealthAsync(payload);
}
catch (DirectivSysException ex)
{
    // Handle DirectivSys-specific errors
    Console.WriteLine($"DirectivSys error: {ex.Message}");
}
catch (HttpRequestException ex)
{
    // Handle network errors
    Console.WriteLine($"Network error: {ex.Message}");
}

Configuration Best Practices

Using Configuration Files

appsettings.json:

{
  "DirectivSys": {
    "ApiKey": "your-api-key",
    "BaseUrl": "https://api.directivsys.com",
    "TimeoutSeconds": 30
  }
}

Program.cs:

builder.Services.AddDirectivSys(options =>
{
    builder.Configuration.GetSection("DirectivSys").Bind(options);
});

Using Environment Variables

builder.Services.AddDirectivSys(options =>
{
    options.ApiKey = Environment.GetEnvironmentVariable("DIRECTIVSYS_API_KEY") 
        ?? throw new InvalidOperationException("DIRECTIVSYS_API_KEY not set");
    options.BaseUrl = Environment.GetEnvironmentVariable("DIRECTIVSYS_BASE_URL") 
        ?? "https://api.directivsys.com";
});

Webhook Security

The webhook endpoint (/directiv/webhook) validates incoming requests using the API key. DirectivSys includes the X-API-Key header automatically when sending webhook notifications.

The validation ensures:

  • Request includes X-API-Key: {your-api-key} header
  • The provided key matches your configured API key
  • Payload can be deserialized to GlobalRecord

Example: Complete Integration

using DirectivSys.Sdk.Extensions;
using DirectivSys.Sdk.Models;
using DirectivSys.Sdk.Models.Payloads;
using DirectivSys.Sdk.Services;

var builder = WebApplication.CreateBuilder(args);

// Configure DirectivSys
builder.Services.AddDirectivSys(options =>
{
    options.ApiKey = builder.Configuration["DirectivSys:ApiKey"]!;
    options.BaseUrl = builder.Configuration["DirectivSys:BaseUrl"] ?? "https://api.directivsys.com";
});

// Add your services
builder.Services.AddControllers();
builder.Services.AddHostedService<InventoryAnalysisWorker>();

var app = builder.Build();

app.UseRouting();
app.MapControllers();
app.MapDirectivWebhook();

// Configure directive callback
var directivSys = app.GetDirectivSys();
directivSys.OnDirectiveReceived = record =>
{
    var logger = app.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Received analytics: {Type} with {Count} directives",
        record.AnalyticsType, record.Directives.Count);

    foreach (var directive in record.Directives)
    {
        // Process each directive
        ProcessDirective(directive, app.Services);
    }
};

app.Run();

void ProcessDirective(Directive directive, IServiceProvider services)
{
    var scope = services.CreateScope();
    
    switch (directive.Action)
    {
        case "reorderSupplier":
            var inventoryService = scope.ServiceProvider.GetRequiredService<IInventoryService>();
            inventoryService.Reorder(directive.Parameters["sku"].ToString()!);
            break;
            
        case "launchPromotion":
            var marketingService = scope.ServiceProvider.GetRequiredService<IMarketingService>();
            marketingService.LaunchCampaign(directive.Targets);
            break;
    }
}

// Background worker to periodically submit analytics
public class InventoryAnalysisWorker : BackgroundService
{
    private readonly DirectivSysClient _client;
    private readonly ILogger<InventoryAnalysisWorker> _logger;

    public InventoryAnalysisWorker(DirectivSysClient client, ILogger<InventoryAnalysisWorker> logger)
    {
        _client = client;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                // Aggregate your data
                var inventoryData = await GetCurrentInventoryAsync();
                
                // Submit to DirectivSys
                await _client.SubmitInventoryHealthAsync(inventoryData, stoppingToken);
                
                _logger.LogInformation("Inventory analysis submitted successfully");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to submit inventory analysis");
            }

            // Run daily
            await Task.Delay(TimeSpan.FromHours(24), stoppingToken);
        }
    }

    private async Task<InventoryHealthPayload> GetCurrentInventoryAsync()
    {
        // Your logic to aggregate inventory data
        return new InventoryHealthPayload
        {
            Sku = "SKU123",
            StockLevel = 45,
            ReorderPoint = 50,
            SafetyStock = 30,
            ForecastedDemandNext30Days = 200
        };
    }
}

Requirements

  • .NET 6.0 or higher
  • ASP.NET Core application (for webhook endpoint)

Support

For issues, questions, or feature requests, please visit:

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


Made with ❤️ by DirectivSys Inc

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 was computed.  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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.9 144 4/21/2026
1.2.8 147 4/10/2026
1.2.7 129 3/14/2026
1.2.6 131 3/9/2026
1.2.5 118 3/9/2026
1.2.4 108 3/8/2026
1.2.3 116 3/7/2026
1.2.1 318 2/4/2026
1.2.0 161 2/2/2026
1.1.9 136 2/1/2026
1.1.8 134 2/1/2026
1.1.7 137 2/1/2026
1.1.6 142 1/31/2026
1.1.5 150 1/20/2026
1.1.4 129 1/20/2026
1.1.3 126 1/19/2026
1.1.2 137 1/19/2026
1.1.1 135 1/18/2026
1.1.0 134 1/10/2026
1.0.1 138 1/9/2026
Loading failed