enlitt() and the standard model
The one public model factory, the one standard model string, and premium wrapping.
enlitt() is the only public model factory this package exports, and
"enlitt-standard" (the ENLITT_STANDARD_MODEL constant) is the only
standard model string. There is no second factory, no OpenAI-shaped client,
and no way to select a personal user, override the standard route's provider,
or convert a NANOUSD amount into credit units from application code — all of
that is either fixed by Enlitt or belongs on Enlitt's own dashboard.
import { enlitt, ENLITT_STANDARD_MODEL } from "@enlitt/sdk/server";
import { generateText } from "ai";
const result = await generateText({
model: enlitt(ENLITT_STANDARD_MODEL),
prompt: "Summarize this support ticket."
});enlitt() returns an ordinary LanguageModelV3 — the same interface the
Vercel AI SDK's own providers implement — so it drops into generateText,
streamText, or any other AI SDK call exactly like a direct provider model
would.
Two modes, one factory
enlitt()'s first argument decides the mode, and the mode is the argument's
type, not a separate flag:
enlitt("enlitt-standard")— Enlitt's own standard model. The business never chooses or pays for the underlying provider; Enlitt's own metering applies.enlitt(myProviderModel, options)— premium mode: transparent middleware around a provider model the business supplied and pays for itself. Every premium call requires a declared charge (see below); there is no default quote.
Both modes require the business's own application secret, resolved once
inside enlitt() through the same path described in
Personal login and business credentials. A missing or
invalid secret is EnlittConfigurationError, thrown before the first
request, identically in both modes — there is no configuration under which
enlitt() returns a model that could reach a provider without Enlitt
mediating it.
Options
interface EnlittOptions {
secretKey?: string; // falls back to ENLITT_SECRET_KEY
baseUrl?: string; // falls back to ENLITT_BASE_URL, then the deployed origin
session?: EnlittSession; // for callers with no ambient session context
rateLimit?: EnlittRateLimitRetryOptions;
onTerminalReportError?: (error: EnlittError) => void;
}baseUrl is validated once at construction (HTTPS required) rather than per
call, and resolves in this order: the option, then ENLITT_BASE_URL, then
the deployed Enlitt origin compiled into the package.
Premium wrapping and the declared charge
A premium call declares its own quote through providerOptions.enlitt,
passed on the AI SDK call itself:
await generateText({
model: enlitt(anthropic("claude-opus-5"), { session }),
prompt,
providerOptions: {
enlitt: {
charge: {
amount: "1250000", // exact NANOUSD integer, as a canonical string
asset: "NANO_USD",
description: "Ticket summarization"
}
}
}
});chargeis required in premium mode and rejected in standard mode — Enlitt's standard route chooses its own model and its own price, so declaring a charge for it is a configuration error, not a no-op.charge.amountis validated as a strictly positive canonical integer string — no sign, fraction, exponent, or leading zero — the same rule the wire itself enforces, and it is carried through unchanged end to end. Nothing in this SDK ever parses a NANOUSD amount into a floating-pointNumber.charge.assetmust be exactly"NANO_USD"; there is no second asset in v1.charge.descriptionis optional and free-text.
Every premium call is managed: there is no "unmanaged" mode and no parameter that opts a call out of Enlitt's admission check. Before the provider is invoked, Enlitt checks the declared charge against the calling user's premium ceiling (see Idempotency and the per-call premium limit); a call that would exceed it is refused with the provider left uninvoked, and the business is never billed for a call Enlitt refused.
See Idempotency for providerOptions.enlitt.idempotencyKey
and Typed errors for what a refusal looks like in code.