npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cle-does-things/llms-sdk

v0.2.0

Published

Unified interface to call OpenAI and Anthropic-compatible LLM APIs from Typescript

Readme

@cle-does-things/llms-sdk

TypeScript / Node.js bindings for llms-sdk, a unified Rust SDK for calling LLM APIs. It exposes the same request/response model for OpenAI-compatible chat completions and the Anthropic Messages API.

Features

  • Single interface for OpenAI and Anthropic requests.
  • Text, image, audio (OpenAI), and document (Anthropic) message parts.
  • Structured JSON output via JSON Schema.
  • Tool / function calling with provider-specific serialization.
  • Streaming responses with text, tool, and reasoning deltas.
  • Configurable transient retry policy.
  • Native NAPI-RS binary for performance (prebuilt for macOS, Linux, Windows on x64 & arm64).

Installation

npm install @cle-does-things/llms-sdk
# or
yarn add @cle-does-things/llms-sdk

Prebuilt binaries are included for the most common platforms. If your platform is not covered, the package will attempt to build from source (Rust toolchain required).

Quick start

import { Llm, ApiType, MessageRole } from '@cle-does-things/llms-sdk'

async function main() {
  const request = {
    apiType: ApiType.OpenAI,
    apiKey: process.env.OPENAI_API_KEY!,
    model: 'gpt-5.4-mini',
    messages: [
      {
        role: MessageRole.User,
        content: [{ text: 'Hello!', type: 'text' }],
      },
    ],
    maxOutputTokens: 256,
    temperature: 0.7,
    stream: false,
    parallelToolCalls: false,
  }

  const llm = new Llm()
  const response = await llm.respond(request)
  console.log(response.message.content)
}

main()

Supported API providers

| Provider | ApiType value | Default base URL | | --------- | --------------- | ------------------------------ | | OpenAI | 'openai' | https://api.openai.com/v1 | | Anthropic | 'anthropic' | https://api.anthropic.com/v1 |

Multimodal input

Image

import { imagePart } from '@cle-does-things/llms-sdk'

const message = {
  role: MessageRole.User,
  content: [
    { text: 'Describe this image.', type: 'text' },
    imagePart('files/cat.jpeg'), // or a Buffer, or a URL
  ],
}

Audio (OpenAI only)

import { audioPart } from '@cle-does-things/llms-sdk'

const message = {
  role: MessageRole.User,
  content: [
    { text: 'Describe this audio.', type: 'text' },
    audioPart('files/audio.wav'), // or a Buffer
  ],
}

Document (Anthropic only)

import { documentPart } from '@cle-does-things/llms-sdk'

const message = {
  role: MessageRole.User,
  content: [
    { text: 'Summarize this document.', type: 'text' },
    documentPart('files/file.pdf'), // or a Buffer, or a URL
  ],
}

Structured output

import type { LlmRequest, OutputFormat } from '@cle-does-things/llms-sdk'

const outputFormat: OutputFormat = {
  name: 'capital',
  description: 'Country capital',
  schema: {
    type: 'object',
    properties: {
      country: { type: 'string' },
      capital: { type: 'string' },
    },
    required: ['country', 'capital'],
  },
}

const request: LlmRequest = {
  /* ... */
  outputFormat,
}

Tool use

import type { LlmRequest, Tool } from '@cle-does-things/llms-sdk'
import { ToolChoice } from '@cle-does-things/llms-sdk'

const tool: Tool = {
  name: 'get_weather',
  description: 'Return weather for a city.',
  parameters: {
    type: 'object',
    properties: {
      city: { type: 'string' },
    },
    required: ['city'],
  },
}

const request: LlmRequest = {
  /* ... */
  tools: [tool],
  toolChoice: ToolChoice.Auto,
}

Streaming

Set stream: true and provide a callback to streamResponse:

const request = { /* ... */ stream: true }

await llm.streamResponse(request, (err, chunk) => {
  if (err) {
    console.error(err)
    return
  }
  if (!chunk) return

  switch (chunk.type) {
    case 'delta':
      process.stdout.write(chunk.textDelta ?? '')
      break
    case 'toolDelta':
      console.log('Tool delta:', JSON.stringify(chunk, undefined, 2))
      break
    case 'thinkingDelta':
      console.log('Thinking:', chunk.thinkingDelta)
      break
    case 'complete':
      console.log('\nDone:', JSON.stringify(chunk.message, undefined, 2))
      break
  }
})

Retry policy

Llm accepts an optional RetryPolicy:

import { Llm } from '@cle-does-things/llms-sdk'

const llm = new Llm({
  maxRetries: 5,
  minRetryInterval: 500,
  maxRetryInterval: 3000,
  base: 2,
})

TypeScript types

All public types are exported from index.d.ts. Key interfaces include:

  • LlmRequest – request payload
  • LlmResponse – complete response
  • Message, MessagePart – conversation model
  • ImagePart, AudioPart, DocumentPart – multimodal parts
  • Tool, ToolCallPart, ToolResultPart – tool use
  • OutputFormat – structured output schema
  • LlmStreamingResponse – streaming discriminated union
  • RetryPolicy – retry configuration

Tests

Unit tests (no API keys required):

yarn test

Integration tests against live APIs (requires OPENAI_API_KEY and/or ANTHROPIC_API_KEY):

RUN_INTEGRATION_TESTS=true OPENAI_API_KEY=... ANTHROPIC_API_KEY=... yarn test

License

MIT