Gravicode.TypeSafeSdk
1.2.0
Prefix Reserved
dotnet add package Gravicode.TypeSafeSdk --version 1.2.0
NuGet\Install-Package Gravicode.TypeSafeSdk -Version 1.2.0
<PackageReference Include="Gravicode.TypeSafeSdk" Version="1.2.0" />
<PackageVersion Include="Gravicode.TypeSafeSdk" Version="1.2.0" />
<PackageReference Include="Gravicode.TypeSafeSdk" />
paket add Gravicode.TypeSafeSdk --version 1.2.0
#r "nuget: Gravicode.TypeSafeSdk, 1.2.0"
#:package Gravicode.TypeSafeSdk@1.2.0
#addin nuget:?package=Gravicode.TypeSafeSdk&version=1.2.0
#tool nuget:?package=Gravicode.TypeSafeSdk&version=1.2.0
TypeSafe .NET SDK
Unofficial, strongly typed .NET 10 client for the TypeSafe System One API, ported from the official Python SDK.
dotnet add package Gravicode.TypeSafeSdk
Ask a question about some text
using TypeSafeSdk;
await using var client = new TypeSafeClient(TypeSafeOptions.FromEnvironment());
var response = await client.SystemOneAsync(
new { document = "I was charged twice. Please fix this ASAP." },
Choice.Create("billing", "technical", "other"));
Console.WriteLine(response.Choices["category"].Choice); // billing
Console.WriteLine(response.Choices["category"].Confidence); // 1
Three kinds of question, one request
var response = await client.SystemOneAsync(
new { document = ticket.Body },
new Dictionary<string, object>
{
["category"] = Choice.Create("billing", "technical", "other"),
["urgent"] = new NoulSchema("Does this need a response within one hour?"),
["tone"] = new ScoreSchema("How frustrated is the customer?", "calm", "annoyed", "angry")
});
var queue = response.Choices["category"].Choice; // a label
var urgent = response.Nouls["urgent"].IsTrue; // a 0..1 value, thresholded
var tone = response.Scores["tone"].NearestLabel; // an expected value on a scale
Every answer carries its full probability distribution, so an ambiguous case is visible instead of hidden behind a single label.
Find things in an image
var options = TypeSafeOptions.FromEnvironment();
options.Headers[TypeSafeConstants.ImagesOptInHeader] = "true"; // images are experimental
await using var client = new TypeSafeClient(options);
var photo = ImageAsset.FromFile("shelf.jpg");
var result = await client.SystemOneAsync(
"<photo>",
new Dictionary<string, object> { ["dog"] = new BoxSchema("The dog") },
model: "jev-preview",
assets: new Dictionary<string, Asset> { ["<photo>"] = photo });
var (x, y, w, h) = result.Boxes["dog"].Box.ToPixels(1920, 1080);
An image can also be placed straight into state, or referenced inside text with using (client.AttachAssets(photo)) { … $"Product: {photo}" … }. Requests with images go out as multipart/form-data.
Typed failures
TypeSafeApiException is the base for every HTTP failure, and each one carries StatusCode, Body, Headers, Endpoint, and RequestId.
catch (TypeSafeRateLimitException ex) { await Task.Delay(ex.RetryAfter ?? TimeSpan.FromSeconds(1)); }
catch (TypeSafeAuthenticationException) { /* 401 — retrying will not help */ }
catch (TypeSafeApiTimeoutException ex) { logger.LogWarning("Timed out after {Timeout}", ex.Timeout); }
Also available: TypeSafeBadRequestException, TypeSafePermissionDeniedException, TypeSafeNotFoundException, TypeSafeUnprocessableEntityException, TypeSafeInternalServerException, TypeSafeApiConnectionException, and TypeSafeApiResponseValidationException.
Retry, timeout, headers
Defaults match the Python SDK: two retries, 0.5 s backoff doubling to a 5 s ceiling with 25% jitter, retrying 408/429/5xx, honouring Retry-After, inside a 30 s budget.
var options = new TypeSafeOptions
{
Timeout = TimeSpan.FromSeconds(20),
Retry = new RetryPolicy(MaxRetries: 4),
Headers = { ["X-Tenant"] = "acme" }
};
Any of it can be overridden per call, alongside extraHeaders and extraBody.
Bodies of 1 KB or more are sent zstd-compressed, as the Python SDK does. Set Compression = RequestCompression.None for a gateway that does not accept compressed bodies.
Tests without a key
await using var client = new TypeSafeClient(new TypeSafeOptions { Simulator = true });
The simulator answers choice, noul, and score questions locally and deterministically (and box with the whole frame at confidence 0 — it cannot see) — no key, no network. It is lexical rather than semantic: it weights rare criteria words above common ones, honours negation, and abstains with a flat distribution when it finds no signal instead of guessing.
Configuration
TypeSafeOptions.FromEnvironment() reads TYPESAFE_API_KEY, TYPESAFE_BASE_URL, TYPESAFE_DEFAULT_MODEL, TYPESAFE_LOG_LEVEL, and TYPESAFE_SIMULATOR. The names are also constants on TypeSafeConstants.
Links
Created by Gravicode Studios, led by Kang Fadhil. AI assistant: Jack — The Code Bender.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- ZstdSharp.Port (>= 0.8.8)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Gravicode.TypeSafeSdk:
| Package | Downloads |
|---|---|
|
Blazor.AI.Decision
Blazor.AI decision intelligence: rules engine, DMN-style decision tables, decision trees, business policies, risk assessment, eligibility, approval workflows and dynamic pricing, with TypeSafe System One integration. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Sync with Python SDK 0.7.5: BoxSchema and BoxAnswer for locating things in images; ImageAsset (bytes, file, base64, stream) uploaded as multipart, by alias, by placement, or via AttachAssets; zstd request compression on by default (TypeSafeOptions.Compression); NaN and Infinity sent as strings; noul questions may omit instructions when an outcome is described; invalid questions and null state rejected before the network.