Read and submit Compute jobs with TypeScript
How to read a Compute job with the TypeScript client, check the response, and retry an uncertain submission with the same request key.
Use LithiComputeClient for one typed job read, then inspect the projection and handle failures with
the same request identity. Your existing agent keeps its model, goal, project context, edits and
final decision; the client exposes the current API operations. Preserve the original idempotency
key when a POST outcome is uncertain.
The example below injects fetch, so it stays local and uses synthetic response data. A client built with your credential and no injected fetch sends requests to your account.
1. Construct the client
Import LithiComputeClient from @lithi-ai/compute-sdk and give it an API base URL and a credential
callback. The callback returns the key when a request needs it, so the key stays in your protected
credential store. The client uses https and accepts http only for exact localhost admission.
The options object also accepts quoteSigners, an injected fetch, allowLocalhost, timeoutMs,
maxRetries, idempotencyKey, caller signal, maxResponseBytes, sleep, and now. The defaults are a
30-second timeout, two retries, and a 4 MiB response limit.
For quote requests, supply quoteSigners: a callback that resolves a key ID to a
ComputeQuoteSignerKey record from your approved registry, or null for an unknown key.
createQuote requires this callback and checks the key's identity, validity window and revocation
state, plus the quote's Ed25519 signature, before returning it. The job-read example below needs no
signer resolver.
import { LithiComputeClient } from '@lithi-ai/compute-sdk';
const JOB = '550e8400-e29b-41d4-a716-446655440000';
const KEY = 'lthi_cmp_' + '0123456789abcdef' + '.' + '0123456789012345678901234567890123456789012';
const client = new LithiComputeClient({
baseUrl: 'https://api.example.test/',
credentials: () => KEY,
maxRetries: 0,
fetch: async () => new Response(JSON.stringify({
ok: true,
data: {
job_id: JOB,
state: 'queued',
state_version: 1,
digest: 'a'.repeat(64),
p_next_action: 'none',
},
}), { status: 200, headers: { 'content-type': 'application/json' } }),
});
const job = await client.getJob(JOB);
console.log(job.state, job.state_version);The key, URL, response, and job ID are synthetic. The injected fetch makes no network request.
2. Make a synthetic read
The client exposes createQuote, createJob, getJob, cancelJob, listJobEvents,
getJobResult, createBatch, getBatch, listBatchResults, prepareArtifact,
completeArtifact, listCapabilities, listUsage, getReceipt, listAgentEvents,
getImpactReport,
compatibilityOpenaiResponses, compatibilityOpenaiChatCompletions,
compatibilityOpenaiEmbeddings, and compatibilityAwsBatch. Each method maps to one registered
operation; there is no nested work namespace.
POST methods use an Idempotency-Key. createJob also requires idempotency_key in its request
body, and an optional method key must match that body value. Reads do not send an idempotency key.
Paged reads accept a limit and cursor and default to a limit of 50.
3. Inspect the returned projection
getJob returns a JobProjection with the job ID, state, state version, digest, and next action.
That projection describes job state. getJobResult returns encrypted result metadata, including
the artifact and evidence digests; it isn't decrypted rows or the artifact bytes. Use the
authorized retrieval flow for the bytes, then verify the returned digest and expected media type.
Request bodies are limited to 64 KiB. Responses default to 4 MiB and may be configured up to 16 MiB. The client validates JSON envelopes, identifiers, request fields, and response identity before returning typed values.
getImpactReport(periodId, selectors?) is a schema-backed reporting read. It can pin a report by
revision or snapshot digest and validates that the returned report matches the requested period and
selection. The method uses the account's finance-automation credential boundary and approved
reporting access; it does not submit Compute work or add a sixth MCP tool.
4. Handle failures and recoveries
LithiComputeError provides code, optional HTTP status, optional serverCode,
p_next_action, and retryable. Its eight codes distinguish unavailable contracts, invalid
requests, credential failures, HTTP failures, invalid responses, network failures, timeouts, and
caller aborts. It retries 408, 425, 429, 500, 502, 503, and 504 within the configured budget.
An abort or timeout ends the client call; it doesn't cancel server work. If a POST outcome is
uncertain, retain its idempotency key and request body, read the existing job, and reuse the same
intent. Call cancelJob only when you mean to request server-side cancellation.
Check the compatibility matrix for version and protocol matching, then use the Work API reference for request and response schemas.
Add the local TypeScript Kit when you need preparation
The TypeScript path is the complete four-module Kit path. Start with the task brief, choose the declared operation and output contract, then use the local helpers to prepare its binding and artifact. Use the API client for wire calls and the supplied Kit package roots for preparation, compilation, workflow coordination and result handling. These helpers do not add MCP tools or grant account authority. They help your agent prepare permitted work and inspect results; they do not replace its goal, context or final decision.
| Local task | Kit surface | What it returns |
|---|---|---|
| Validate records and decide what may leave | @lithi/kit-data → prepareRecords, preparedBinding | A prepared copy, one of blocked, review_required or eligible, protected local evidence, and an eligible preparation commitment |
| Preserve scoped relationships | @lithi/kit-data → createAliasScope, aliasFor, restoreOutputs | Scoped aliases and an item- and field-scoped restoration result; the reverse map stays local |
| Compile, split and seal eligible input | @lithi/kit-core → compile exports such as splitUnits, sealUnitsFromSplitPieces, and sealBlocks | A bounded plan or a refusal, then encrypted blocks and a content-free manifest |
| Bind approval and submit the matching intent | @lithi/kit-core → bindApproval, submitApprovedJob | An approval record or a submission outcome that preserves the original intent when delivery is uncertain |
| Coordinate declared stages | @lithi/kit-workflows → planRun, runPlan, resumeRun | A deterministic plan, checkpointed state and a resumable run report |
| Check and deliver an accepted result | Core result helpers such as checkResultDescriptor and deliverResult | Named verification levels and a local destination commit; the caller supplies transfer, decryption, schema and coverage boundaries |
Each package exposes its public API from its root entry point. Use the exact local release and its package metadata; package names do not imply a public package-registry installation or a separate delivery subpath. The helpers run locally until the caller separately authorizes transfer or execution. Check the client matrix for the supported release, then read What leaves your machine and verify the result files.
See Kit contents for the supplied modules and workflow guides, and the Kit helper reference for exact exports.