Use cancellation aware Compute calls in .NET
How to read a Compute job from .NET with cancellation, and the difference between cancelling your call and cancelling the job.
Use LithiClient with await for one cancellation-aware job read. Your existing agent keeps its
model, goal, project context and final decision; this client exposes the current API operations.
Treat caller cancellation separately from a server-side job cancellation.
The example below injects an HttpMessageHandler, so it stays local and uses synthetic response data. A client built with your credential and the default handler sends requests to your account.
1. Construct the client
Use the Lithi.Client namespace and target net8.0. Construct LithiClient with an
HttpClient whose BaseAddress is set, plus a credential callback of type
Func<CancellationToken, ValueTask<string>>.
using System.Net;
using System.Net.Http;
using System.Text;
using Lithi.Client;
var handler = new FakeHandler();
using var http = new HttpClient(handler) { BaseAddress = new Uri("https://api.example.test/") };
using var client = new LithiClient(
http,
_ => ValueTask.FromResult("lthi_cmp_" + "0123456789abcdef" + "." + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefg"),
maxRetries: 0);
var job = await client.GetJobAsync("550e8400-e29b-41d4-a716-446655440000");
Console.WriteLine(job.GetProperty("state").GetString());
sealed class FakeHandler : HttpMessageHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var json = "{\"ok\":true,\"data\":{\"job_id\":\"550e8400-e29b-41d4-a716-446655440000\",\"state\":\"queued\",\"state_version\":1,\"digest\":\"" + new string('a', 64) + "\",\"p_next_action\":\"none\"}}";
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(json, Encoding.UTF8, "application/json"),
});
}
}The handler returns synthetic JSON, so this example makes no network request. GetJobAsync returns
a Task<JsonElement>; await it before inspecting the projection.
2. Make an asynchronous read
The client exposes CreateQuoteAsync, CreateJobAsync, GetJobAsync, CancelJobAsync,
ListJobEventsAsync, GetJobResultAsync, CreateBatchAsync, GetBatchAsync,
ListBatchResultsAsync, PrepareArtifactAsync, CompleteArtifactAsync,
ListCapabilitiesAsync, ListUsageAsync, GetReceiptAsync, ListAgentEventsAsync,
CompatibilityOpenaiResponsesAsync, CompatibilityOpenaiChatCompletionsAsync,
CompatibilityOpenaiEmbeddingsAsync, and CompatibilityAwsBatchAsync. They are flat methods on
LithiClient and return Task<JsonElement>.
POST methods require a stable idempotency key. Page methods take a limit from 1 through 100 and an
optional cursor; their default limit is 50. Request bodies are capped at 65,536 UTF-8 bytes.
The defaults are a 30-second timeout, two retries, and a 4 MiB response cap. maxRetries may be
0 through 8, and maxResponseBytes may be up to 16 MiB.
3. Handle cancellation and typed errors
A caller CancellationToken cancels the HTTP operation and maps to SDK_ABORTED. A request
deadline maps to SDK_TIMEOUT. Neither one cancels an admitted Compute job. Call
CancelJobAsync for that server operation.
LithiComputeException exposes Code, optional HTTP Status, optional ServerCode, and
PNextAction. The transport retries 408, 425, 429, 500, 502, 503, and 504 when the operation is
idempotent and the retry budget allows it.
GetJobAsync returns state, version, digest, and next action. GetJobResultAsync returns encrypted
artifact metadata and digests, not decrypted rows or bytes. Retrieve authorized bytes separately,
then verify the digest and media type. If a POST outcome is uncertain, preserve its key and body,
read the existing job, and reuse the same intent.
Check the .NET compatibility row, then use the Work API reference for wire schemas.
The .NET wire client has no monthly-report operation. Reading that report needs separate permission and an approved reporting API or file path; it remains outside the five MCP work tools.
.NET supplies the wire client
The supplied .NET source provides the asynchronous Compute wire client, JSON contract checks, bounded retries and cancellation handling. It does not include the TypeScript Kit's local record preparation, pseudonymization, compile/seal workflow or complete result-delivery steps. Check the client matrix before choosing caller-supplied helpers; a client call does not grant transfer or execution authority.
The Lithi.Client package identity does not imply a public package-registry install. Use the exact
local source and release supplied to your project. For the support-ticket example, read What
leaves your machine, then verify result files
before choosing result delivery. The Kit helper reference
shows the local helper coverage available in other languages.
See Kit contents for the supplied modules and Kit helper reference for exact local exports.