LiteGraph.Sdk 10.1.0

dotnet add package LiteGraph.Sdk --version 10.1.0
                    
NuGet\Install-Package LiteGraph.Sdk -Version 10.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.

                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.

                    
Directory.Packages.props

                    
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 LiteGraph.Sdk --version 10.1.0
                    
#r "nuget: LiteGraph.Sdk, 10.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 LiteGraph.Sdk@10.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=LiteGraph.Sdk&version=10.1.0
                    
Install as a Cake Addin
#tool nuget:?package=LiteGraph.Sdk&version=10.1.0
                    
Install as a Cake Tool

LiteGraph C# SDK

NuGet Version NuGet

This SDK is part of the LiteGraph monorepo. For other language SDKs, see the SDK overview.

LiteGraph is a property graph database with support for graph relationships, tags, labels, metadata, data, and vectors. LiteGraph is intended to be a unified database for providing persistence and retrieval for knowledge and artificial intelligence applications.

Current release: v10.1.0.

New in v10.0.0

  • Cluster administration on sdk.Admin: ReadClusterNodes, ReadClusterNode(nodeId), RestartCluster (rolling restart, one node at a time), RestartClusterNode(nodeId), DeleteClusterNode(nodeId) (removes an Offline or Stopped node from the registry), ReadClusterLocks (distributed locks the cluster holds in Clutch, with the node holding each), and ReadClusterJobs (most recent run of each cluster singleton job). RestartServer now returns a ClusterRestartResult.
  • sdk.HealthLive() and sdk.HealthReady() return the health body; readiness returns it for both 200 and 503, so a node that is not ready reports why.
  • Automatic retries: connection failures and 502, 503, and 504 responses are retried with exponential backoff and jitter (MaxRetries, default 2; RetryBaseDelayMs, default 200, capped at 5000). GET, HEAD, PUT, and DELETE are retried; POST only when RetryPost is true. Streams are never retried once any of the body has been read.
  • sdk.LastNodeId names the node that answered the most recent request (the x-litegraph-node header).
  • Request history on sdk.RequestHistory: Search (one page), Enumerate (every page), ReadByGuid, ReadDetail (captured headers and bodies), ReadSummary (counts bucketed by interval), DeleteByGuid, and DeleteMany. Filters include NodeId, the node that handled each request.

Request history

RequestHistorySearchRequest search = new RequestHistorySearchRequest
{
    NodeId = "litegraph-2",          // only requests handled by this node
    Success = false,                 // only failures
    FromUtc = DateTime.UtcNow.AddHours(-1),
    MaxKeys = 100
};

EnumerationResult page = await sdk.RequestHistory.Search(search);
foreach (RequestHistoryEntry entry in page.Objects)
    Console.WriteLine(entry.CreatedUtc + " " + entry.Method + " " + entry.Path + " " + entry.StatusCode + " on " + entry.NodeId);

await foreach (RequestHistoryEntry entry in sdk.RequestHistory.Enumerate(search))
{
    RequestHistoryDetail detail = await sdk.RequestHistory.ReadDetail(entry.GUID);
}

RequestHistorySummary summary = await sdk.RequestHistory.ReadSummary("hour", DateTime.UtcNow.AddDays(-1), DateTime.UtcNow);
RequestHistoryDeleteResult deleted = await sdk.RequestHistory.DeleteMany(new RequestHistorySearchRequest { Path = "/v1.0/health" });

System administrators see every tenant and may set TenantGUID; tenant administrators see only their own tenant. Enumerate pins its window to the moment it starts (unless ToUtc is set), so requests recorded while it pages do not shift later pages.

Behind a load balancer

A LiteGraph cluster runs several identical nodes behind a load balancer, so any request may be answered by any node. The SDK needs no special configuration for this, but two settings help:

LiteGraphSdk sdk = new LiteGraphSdk("http://127.0.0.1:8701", "litegraphadmin");
sdk.MaxRetries = 3;          // retries after the first attempt (0 to 10)
sdk.RetryBaseDelayMs = 250;  // first retry delay; doubles per retry, capped at 5000 ms
sdk.RetryPost = false;       // POST is not idempotent; enable only for operations safe to repeat

ClusterStatus cluster = await sdk.Admin.ReadClusterNodes();
foreach (ClusterNode node in cluster.Nodes)
    Console.WriteLine(node.NodeId + " " + node.State + (node.RestartPending ? " (restart pending)" : ""));

Console.WriteLine("Last request answered by " + sdk.LastNodeId);

HealthResponse ready = await sdk.HealthReady();
Console.WriteLine(ready.Status + " database=" + ready.Checks.Database + " clutch=" + ready.Checks.Clutch + " redis=" + ready.Checks.Redis);

A node that is restarting or briefly unreachable returns 502 or 503 through the load balancer; the retries absorb it. LastNodeId is useful when reporting a problem, because it names the node whose logs to read.

New in v8.1.0

  • Added sdk.Chat methods covering the LiteGraph chat surface: endpoint management, completions (non-streaming and SSE streaming), threads, turns, feedback, endpoint health, and per-tenant chat settings
  • Breaking: every list-returning read method (ReadMany, ReadAllInTenant, ReadAllInGraph, ReadByGuids, ReadNodeEdges, ReadParents, ReadChildren, ReadNeighbors, ReadMostConnected, ReadLeastConnected, ReadEdgesFromNode, ReadEdgesToNode, ReadEdgesBetweenNodes, chat reads, ListBackups, GetTenantsForEmail, and SearchVectors) now returns an EnumerationResult pagination envelope instead of a raw List. Access records via .Objects, and use TotalRecords, RecordsRemaining, EndOfResults, and ContinuationToken for paging. Most read methods accept optional maxKeys (1-1000, default 1000), skip, order, and continuationToken parameters.

Paginated reads

All list-shaped GET routes return the enumeration envelope:

EnumerationResult page = await sdk.Node.ReadMany(
    tenantGuid,
    graphGuid,
    order: EnumerationOrderEnum.CreatedDescending,
    skip: 0,
    maxKeys: 100);

foreach (Node node in page.Objects) Console.WriteLine(node.Name);
Console.WriteLine($"{page.TotalRecords} total, {page.RecordsRemaining} remaining, end: {page.EndOfResults}");

// Continue the enumeration with the returned token
if (!page.EndOfResults && page.ContinuationToken != null)
{
    EnumerationResult next = await sdk.Node.ReadMany(
        tenantGuid,
        graphGuid,
        maxKeys: 100,
        continuationToken: page.ContinuationToken);
}

New in v7.0.0

  • Added v7 graph transaction diagnostics, lifecycle state, and isolation-level models
  • Added transaction execution helpers aligned with the REST v7 transaction response body
  • Updated SDK metadata for the LiteGraph v7.0.0 release

New in v6.0.2

  • Added BulkCreateReturnModeEnum overloads for label, tag, vector, node, and edge CreateMany methods
  • Added minimal bulk create responses while preserving existing full-response defaults
  • Updated bulk create documentation and route coverage

New in v6.0.0

  • Native graph query, graph transaction, authorization, and request history client helpers
  • v6 request/response models for query, transaction, and authorization workflows
  • API coverage aligned with the LiteGraph v6.0.0 REST surface

Bugs, Feedback, or Enhancement Requests

Please feel free to start an issue or a discussion!

Example

Refer to the Test.Sdk project for a full example.

using LiteGraph.Sdk;

LiteGraphSdk sdk = new LiteGraphSdk("http://localhost:8701", "default");
Guid tenantGuid = Guid.Parse("00000000-0000-0000-0000-000000000000");

Graph graph = sdk.Graph.Create(new Graph { TenantGUID = tenantGuid, Name = "My graph" });
Node node1 = sdk.Node.Create(new Node { TenantGUID = tenantGuid, GraphGUID = graph.GUID, Name = "My node 1" });
Node node2 = sdk.Node.Create(new Node { TenantGUID = tenantGuid, GraphGUID = graph.GUID, Name = "My node 2" });
Edge edgeFrom1To2 = sdk.Edge.Create(new Edge { TenantGUID = tenantGuid, GraphGUID = graph.GUID, From = node1.GUID, To = node2.GUID });

Graph Transactions

Graph transactions execute create, update, delete, attach, detach, and upsert operations atomically inside one tenant and graph. Failed execution returns a TransactionResult with Success = false and diagnostics. Request validation failures set ValidationFailure = true; provider execution failures set RolledBack = true.

Guid adaGuid = Guid.NewGuid();
Guid graceGuid = Guid.NewGuid();

TransactionRequest request = sdk.Transaction.CreateRequestBuilder()
    .WithMaxOperations(10)
    .WithTimeoutSeconds(30)
    .WithIsolationLevel(TransactionIsolationLevelEnum.Default)
    .CreateNode(new Node { GUID = adaGuid, Name = "Ada" })
    .CreateNode(new Node { GUID = graceGuid, Name = "Grace" })
    .CreateEdge(new Edge { From = adaGuid, To = graceGuid, Name = "Worked With" })
    .Build();

TransactionResult result = await sdk.Transaction.Execute(tenantGuid, graph.GUID, request);

Console.WriteLine($"{result.Success} {result.State} {result.TransactionId} {result.DurationMs}ms");

TransactionResult includes lifecycle state, validation-failure state, provider, isolation, commit/rollback timing, retryability, concurrency-conflict, provider error code, and whether the request used an isolated transaction repository or the legacy serialized fallback.

Chat

The sdk.Chat property wraps the LiteGraph chat surface: chat endpoints (upstream completion and embedding providers), the model catalog, completions, threads, feedback, endpoint health, and per-tenant chat settings. Completions, thread creation, and feedback submission require a user principal, so instantiate the SDK with email, password, and tenant GUID (or a user-linked credential) for those calls.

Endpoint management

ChatEndpoint endpoint = await sdk.Chat.CreateEndpoint(new ChatEndpoint
{
    TenantGUID = tenantGuid,
    Name = "Local Ollama",
    EndpointType = ChatEndpointTypeEnum.Completion,
    Provider = ChatProviderTypeEnum.Ollama,
    Endpoint = "http://127.0.0.1:11434",
    Model = "gemma3:4b",
    ContextWindowTokens = 131072    // optional; caps the conversation-history budget
});

ChatEndpoint embedding = await sdk.Chat.CreateEndpoint(new ChatEndpoint
{
    TenantGUID = tenantGuid,
    Name = "Embeddings",
    EndpointType = ChatEndpointTypeEnum.Embedding,
    Provider = ChatProviderTypeEnum.OpenAI,
    Endpoint = "https://api.openai.com",
    ApiKey = "sk-...",
    Model = "text-embedding-3-small"
});

EnumerationResult completionEndpoints = await sdk.Chat.ReadEndpoints(tenantGuid, ChatEndpointTypeEnum.Completion);
Console.WriteLine($"{completionEndpoints.TotalRecords} completion endpoints");
ChatEndpoint read = await sdk.Chat.ReadEndpoint(tenantGuid, endpoint.GUID);
ChatEndpointTestResult test = await sdk.Chat.TestEndpoint(tenantGuid, endpoint.GUID);
Console.WriteLine($"Reachable: {test.Reachable}, model exists: {test.ModelExists}");

EnumerationResult health = await sdk.Chat.ReadAllEndpointHealth(tenantGuid);
ChatEndpointHealth one = await sdk.Chat.ReadEndpointHealth(tenantGuid, endpoint.GUID);

API keys are redacted to their last four characters in every response; sending a redacted value back on update preserves the stored key. UpdateEndpoint and DeleteEndpoint complete the management surface; EndpointExists performs a lightweight HEAD check.

Model catalog

Non-admin callers can enumerate the active endpoints available to them, projected down to what a model picker needs (no URLs, keys, or health configuration):

EnumerationResult models = await sdk.Chat.ReadModels(tenantGuid);
foreach (ChatModelSummary model in models.Objects)
{
    Console.WriteLine($"{model.Name} ({model.Provider}/{model.Model}, {model.EndpointType}) default: {model.IsDefault}");
}

Pass a summary's GUID as CompletionEndpointGUID or EmbeddingEndpointGUID on a completion request to select it.

Non-streaming completion

ChatCompletionResult result = await sdk.Chat.Completion(tenantGuid, new ChatCompletionRequest
{
    Message = "What are the most connected nodes in this graph?",
    GraphGUID = graph.GUID
});

Console.WriteLine(result.Message);
Console.WriteLine($"Thread {result.ThreadGUID}, {result.CompletionTokens} tokens, {result.TotalDurationMs}ms");

Omitting ThreadGUID creates a new thread bound to GraphGUID; pass the returned ThreadGUID on the next call to continue the conversation.

Streaming completion

await foreach (ChatStreamEvent ev in sdk.Chat.CompletionStreaming(tenantGuid, new ChatCompletionRequest
{
    Message = "Summarize this graph.",
    GraphGUID = graph.GUID
}))
{
    if (ev.Event == "delta") Console.Write(ev.Content);
    else if (ev.Event == "tool_call") Console.WriteLine($"[tool: {ev.Name}]");
    else if (ev.Event == "usage") Console.WriteLine($"\n{ev.Usage.CompletionTokens} tokens");
    else if (ev.Event == "error") Console.WriteLine($"error: {ev.Message}");
}

Threads, feedback, and settings

List threads = (await sdk.Chat.ReadThreads(tenantGuid)).Objects;
List turns = (await sdk.Chat.ReadThreadTurns(tenantGuid, threads[0].GUID)).Objects;

// Rename a thread (only Title is honored)
await sdk.Chat.UpdateThread(tenantGuid, threads[0].GUID, new ChatThread { Title = "Renamed thread" });
await sdk.Chat.DeleteThread(tenantGuid, threads[0].GUID);

// Feedback: submit as a user; read and delete require admin
ChatFeedback feedback = await sdk.Chat.SubmitFeedback(tenantGuid, turns[0].GUID, ChatFeedbackRatingEnum.ThumbsUp, "Great answer");
EnumerationResult allFeedback = await sdk.Chat.ReadFeedback(tenantGuid);
await sdk.Chat.DeleteFeedback(tenantGuid, feedback.GUID);

ChatSettings settings = await sdk.Chat.ReadChatSettings(tenantGuid);
settings.DefaultCompletionEndpointGUID = endpoint.GUID;
settings.DefaultEmbeddingEndpointGUID = embedding.GUID;
await sdk.Chat.UpdateChatSettings(settings);

Version History

Please refer to CHANGELOG.md for version history.

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 (1)

Showing the top 1 NuGet packages that depend on LiteGraph.Sdk:

Package Downloads
View.Sdk

C# SDK for View AI.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.1.0 67 10/4/2026
10.0.0 102 9/30/2026
9.0.0 93 9/29/2026
8.1.0 100 9/2/2026
7.0.0 285 6/19/2026
6.0.3 124 6/13/2026
6.0.0 134 4/18/2026
5.0.0 1,048 11/27/2025
4.1.2 988 11/19/2025
4.1.1 1,179 11/5/2025
4.1.0 2,823 7/22/2025
4.0.9 743 7/3/2025
4.0.8 227 7/1/2025
4.0.6 274 6/22/2025
4.0.5 206 6/22/2025
4.0.4 248 6/5/2025
4.0.3 270 5/28/2025
4.0.2 241 5/27/2025
4.0.1 250 5/26/2025
4.0.0 281 4/22/2025
Loading failed

v10.1.0: RestWrapper 3.3.1.