SDK

@vovix/llm is a small typed client for Node.js services. It depends on nothing but fetch: no AWS SDK, no credentials, so it runs anywhere your service does.

Official SDK

TypeScript · @vovix/llm

Typed client for Node.js services. Uses fetch only — no AWS SDK, no IAM — and retries gateway throttles for you.

Read more

Install

npm install @vovix/llm

It has no runtime dependencies and needs Node.js 18 or later for fetch. The package is published from packages/sdk of the vovix-core repository: npmjs.com/package/@vovix/llm.

Create a client

import { createClient } from '@vovix/llm'

const llm = createClient({
  baseUrl: 'https://api.llm.vovix.io/v1',
  apiKey: process.env.LLM_API_KEY!,
})
  • Name
    baseUrl
    Type
    string
    Description

    The API base URL, including /v1 and without a trailing slash.

  • Name
    apiKey
    Type
    string
    Description

    Your service's API key. Sent as x-api-key.

  • Name
    timeoutMs
    Type
    number
    Description

    Budget for the whole call, every retry included. Default 120000.

  • Name
    maxAttempts
    Type
    number
    Description

    Total attempts, including the first. Default 3.

  • Name
    fetch
    Type
    typeof fetch
    Description

    Replace the fetch implementation — for tests, or to pin DNS.

Methods

MethodEndpoint
llm.chat(req)POST /v1/chat
llm.object<T>(req)POST /v1/objects
llm.runAgent(req)POST /v1/agents/run, once per turn — see Agents
llm.agent(req)POST /v1/agents/run, one turn
llm.usage()GET /v1/usage
llm.models()GET /v1/models

Retries

The SDK retries what the gateway returns when it is busy: 429 from your usage plan, and 500, 502, 503, 504. It waits with exponential backoff and full jitter, honours retry-after (capped at 20 seconds), and gives up when maxAttempts or timeoutMs runs out.

It never retries BUDGET_EXCEEDED: the daily budget resets at midnight UTC, so another attempt only spends another request. Upstream model throttling is already retried inside the API before you see an error.

Errors

Every failure is a VovixLlmError — including timeouts and network failures, which never reach the API. Branch on code, not message: messages can change.

import { VovixLlmError } from '@vovix/llm'

try {
  await llm.chat({ model: 'google.gemma-3-12b-it', messages, maxTokens: 400 })
} catch (e) {
  if (e instanceof VovixLlmError && e.code === 'BUDGET_EXCEEDED') {
    // degrade gracefully until midnight UTC
  }
  throw e
}
  • Name
    status
    Type
    number
    Description

    HTTP status of the final attempt, or 0 when no response was received.

  • Name
    code
    Type
    string
    Description

    The API error code — see Errors — or one of the client-side codes below.

  • Name
    requestId
    Type
    string
    Description

    Upstream request id, when the model was reached. Include it when reporting a problem.

Client-side codes

These are raised by the SDK itself, when there is no API response to read a code from.

StatusCodeMeaning
0TIMEOUTThe whole call, every retry included, ran past timeoutMs.
0NETWORKThe request couldn't reach the API (DNS, TLS, connection reset) after retries.
anyBAD_RESPONSEThe API answered with a success status but a body that isn't JSON.

Was this page helpful?