Reliable LLM calls,
by default.
A lightweight resilience layer for OpenAI-compatible chat completions: retries, timeouts, caching, and circuit breaking, dependency-light and typed from the start.
$ npm install vern-llmimport OpenAI from 'openai';
import { VernLLM } from 'vern-llm';
export const llm = new VernLLM({
client: new OpenAI({ apiKey: process.env.OPENAI_API_KEY }),
model: 'gpt-4o',
maxRetries: 3,
timeoutMs: 10_000,
circuitBreaker: true,
onUsage: ({ totalTokens }) => {
console.log(`Used ${totalTokens} tokens`);
},
});
export const summary = await llm.cachedLLMCall({
cacheKey: `resume:${resumeId}`,
ttl: 3600,
call: {
systemPrompt: 'Analyze this resume and return structured hiring insights.',
userContent: resumeText,
schema: HiringSummarySchema, // Zod schema
},
});One config. Every failure mode covered.
maxRetries: 3→ 3 attempts with exponential backofftimeoutMs: 10_000→ 10s hard timeout per attemptcircuitBreaker: true→ trips after repeated failuresonUsage→ token usage reported per callcachedLLMCall→ identical calls skip the networkschema→ response validated and typed via Zod
maxRetries: 3Retry with backoff
Retries a failed call up to N times with exponential backoff and jitter between attempts.
timeoutMs: 10_000Per-attempt timeout
Each attempt is raced against a hard timeout, so no single request can hang the call.
circuitBreaker: trueCircuit breaker
Trips after repeated failures and rejects immediately while open, call getCircuitState() to inspect it.
nonRetryableStatus: [400, 401, 403]Fail-fast status codes
Status codes you mark as non-retryable skip the retry loop entirely, no point retrying a 401.
llm.cachedLLMCall({ cacheKey, ttl, call })Caching
Wraps call() with a pluggable cache adapter, identical calls return without hitting the network.
schema: HiringSummarySchemaStructured output
Pass a Zod schema inside call params, get back parsed, validated, typed JSON or a validation error.
onUsage: ({ totalTokens }) => {}Usage tracking
Reports prompt, completion, and total tokens per call, only fires when the provider returns usage data.
logger: myLoggerPluggable logger
Bring your own Logger implementation, or fall back to the built-in console logger gated by debug.
Why vern-llm?
Every project calling an LLM API ends up writing the same defensive code; retry logic, timeouts, a circuit breaker, a cache layer, usually copied between projects and slightly wrong each time.
vern-llm is a thin, dependency-light wrapper that gives you these primitives with sensible defaults out of the box, and lets you override exactly what you need. It works with any OpenAI-compatible client, plus Anthropic, Gemini, and Bedrock adapters. No vendor lock-in.