Enlitt

Models and pricing

Use the Vercel or OpenAI adapter for standard and premium calls.

Choose the adapter that matches your existing model code. Both use the same session, admission checks, and premium settlement lifecycle.

Standard calls with the Vercel AI SDK

import { enlitt, ENLITT_STANDARD_MODEL } from "@enlitt/sdk/vercel";
import { generateText, streamText } from "ai";

// Run inside session middleware, or pass { session } to enlitt().
const model = enlitt(ENLITT_STANDARD_MODEL);
const result = await generateText({ model, prompt: "Explain photosynthesis." });
console.log(result.text);

const stream = streamText({ model, prompt: "Explain photosynthesis." });
for await (const text of stream.textStream) {
  process.stdout.write(text);
}

The standard model has a minimal, stable contract:

  • Text input and output, with streaming or non-streaming responses.
  • Bounded PNG and JPEG image input.
  • Automatic function tools, with calls and results across steps; omitting tools disables tool calling.
  • Output-token limits, cancellation, normalized usage, and a finish reason.
  • At least 131,072 context tokens and 32,768 output tokens.

The SDK rejects locally unsupported standard options: forced tool choice, structured-output enforcement, sampling and parallel-tool controls, files, audio/video input, reasoning controls, and provider-specific options. The standard identifier does not promise every feature of either adapter's underlying SDK.

Premium calls with the Vercel AI SDK

Wrap a provider model you already configure and pay for. The example accepts that model so it does not assume a particular provider or model name:

import { enlitt, type EnlittTarget } from "@enlitt/sdk/vercel";
import { generateText } from "ai";

type ProviderModel = Exclude<EnlittTarget, string>;

export async function summarize(myProviderModel: ProviderModel, prompt: string) {
  return generateText({
    model: enlitt(myProviderModel),
    prompt,
    providerOptions: {
      enlitt: {
        maxCharge: "10000000", // Reserve up to $0.01, subject to the user's limits.
        price: "5000000" // Charge $0.005 on completion or cancellation.
      }
    }
  });
}

Enlitt checks the session and spending capacity before invoking your provider. If admission succeeds, your server calls the provider directly. You still supply and pay for the provider credentials. A failed provider call charges the user zero; provider errors propagate to your code unchanged.

Maximum and actual price

All monetary inputs are NANOUSD integer strings: "1000000000" is $1, "10000000" is $0.01, and "0" is valid. Use BigInt for arithmetic; never send decimals, signs, exponent notation, or leading zeros.

OptionsBehavior
Constant price onlyThe maximum defaults to that price.
maxCharge and constant priceReserves the maximum; charges the constant, capped by the effective maximum. The constant cannot exceed your declared maximum.
maxCharge and function priceRuns the function once on completion or cancellation and caps its result.
maxCharge without priceAccounts the call but charges zero.
Function price without maxCharge, or neither fieldRejected before a network request.

The old charge object is unsupported. Use maxCharge and price instead. Both are forbidden on standard calls.

For token-based pricing, supply rates in NANOUSD per token. These example rates are illustrative, not a provider price list:

import { perToken } from "@enlitt/sdk/vercel";

const pricing = {
  maxCharge: "10000000",
  price: perToken({ input: "100", output: "200" })
};
// Pass pricing as providerOptions.enlitt on your premium AI SDK call.

perToken multiplies total input and output token counts using exact integer arithmetic. Missing usage counts as zero. Cached and reasoning tokens are included in the corresponding totals. A custom function receives usage, output, timing, status, and effectiveMaxChargeNanoUsd in your server process. It never runs for failed calls. If pricing throws or returns an invalid value, the charge is zero and onTerminalReportError receives the error.

OpenAI Responses adapter

The standard path needs no OpenAI provider client:

import { enlitt, ENLITT_STANDARD_MODEL } from "@enlitt/sdk/openai";

const client = enlitt();
const response = await client.responses.create({
  model: ENLITT_STANDARD_MODEL,
  input: "Explain photosynthesis."
});
console.log(response.output_text);

For premium, wrap your existing official OpenAI client. Set the example OPENAI_MODEL environment variable to a model available to your provider account:

import OpenAI from "openai";
import { enlitt } from "@enlitt/sdk/openai";

const model = process.env.OPENAI_MODEL;
if (!model) throw new Error("Set OPENAI_MODEL on the server");

// OpenAI reads your server's OPENAI_API_KEY; Enlitt reads ENLITT_SECRET_KEY.
const client = enlitt(new OpenAI());
const response = await client.responses.create({
  model,
  input: "Summarize this support ticket.",
  enlitt: { maxCharge: "10000000", price: "5000000" }
});
console.log(response.output_text);

This adapter supports responses.create() only. It does not expose Chat Completions, embeddings, images, audio, Realtime, background responses, or Responses helper methods such as parse, retrieve, and stream. For streaming, pass stream: true to responses.create() and consume the returned async iterable with for await. Consume or cancel streams so their terminal outcome can be reported. await and for await are supported; OpenAI's .withResponse() and stream helper objects are not.

Call options and reporting

Both adapters accept construction options for secretKey, baseUrl, session, rateLimit, and onTerminalReportError. The key defaults to ENLITT_SECRET_KEY; baseUrl defaults to ENLITT_BASE_URL, then the deployed API origin, and must use HTTPS.

Vercel per-call options go in providerOptions.enlitt; OpenAI per-call options go in the request's enlitt field. Both support idempotencyKey and string metadata. Metadata is limited to 16 entries, 64-character keys, and 512-character values; keys cannot start with enlitt_.

Premium calls may set reportingDeadlineMs to allow enough time for generation and pricing. Enlitt bounds that deadline by server policy. A call that expires before settlement charges zero. Reporting failure is sent to onTerminalReportError and does not replace the provider's result or error.

For a direct SDK call or raw HTTP request outside these adapters, use withPremiumCharge(). See Spending limits and Idempotency before adding retries.

On this page