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 🙏

© 2025 – Pkg Stats / Ryan Hefner

ucai-sdk

v0.1.1

Published

JavaScript SDK for UCAI API

Readme

UCAI SDK · JavaScript

A ~3 kB, zero-dependency wrapper that lets any web or Node app talk to an OpenAI-compatible relay (for example https://ucai.ngrok.app/api/v1).

It supports everything in the modern spec:

  • streaming chat
  • tool (function) calls
  • JSON-schema responses
  • plugins (web search, PDF parsing, …)
  • multimodal images & PDFs
  • image generation (dall-e-2/3, gpt-image-1)

…and ships helpers so you never hand-craft request JSON again.


1 · Quick start

npm i ucai-sdk          # or drop dist/ucai.iife.js in a <script>
import { UCAI } from 'ucai-sdk/dist/ucai.esm.js';

const ai = new UCAI({
  baseUrl: 'https://ucai.ngrok.app/api/v1',
  apiKey : 'sk-YOUR-KEY',
});

Zero-build via CDN

<script type="module">
  import { UCAI } from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/ucai.esm.js';
  const ai = new UCAI({ baseUrl:'…', apiKey:'…' });
</script>

ES5 global

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ucai.iife.js"></script>
<script>
  const ai = new UCAI.UCAI({ baseUrl:'…', apiKey:'…' });
</script>

2 · Core calls

2.1 Plain chat

const res = await ai.chat({
  messages: [{ role:'user', content:'Summarise tokenisation in one line' }],
});
console.log(res.choices[0].message.content);

2.2 Streaming chat

const { stream } = await ai.chat({
  stream: true,
  messages: [{ role:'user', content:'Write a haiku about code' }],
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices?.[0]?.delta?.content || '');
}

2.3 Abort mid-stream

const { stream, controller } = await ai.chat({ …, stream:true });
setTimeout(() => controller.abort(), 2000);

3 · Tool calling (functions)

const tools = [
  {
    schema: {
      name: 'getPi',
      description: 'Returns π with given decimals',
      parameters: {
        type: 'object',
        properties: { d: { type:'integer', minimum:1, maximum:10 } },
        required: ['d'],
      },
    },
    func: ({ d }) => +Math.PI.toFixed(d),
  },
];

const out = await ai.chat({
  messages: [
    { role:'system', content:'You can call getPi' },
    { role:'user',   content:'Give me pi with 5 decimals' },
  ],
  tools,
});
console.log(out.choices[0].message.content);

4 · Structured JSON answers

const schema = {
  name: 'projectIdea',
  strict: true,
  schema: {
    type: 'object',
    properties: {
      idea:       { type:'string' },
      difficulty: { type:'integer', minimum:1, maximum:10 },
    },
    required: ['idea','difficulty'],
  },
};

const out = await ai.chat({
  messages: [{ role:'user', content:'Side-project idea in JSON' }],
  schema,
  validateSchema: true,          // optional runtime AJV check
});
console.log(out.parsed);         // already JSON.parse’d

5 · Plugins (server-side helpers)

import { PLUGIN } from 'ucai-sdk/dist/ucai.esm.js';

const news = await ai.chat({
  messages: [{ role:'user', content:'Latest news on Google I/O 2025?' }],
  plugins : [PLUGIN.web],        // web-search plugin
});
console.log(news.choices[0].message.content);

Combine freely:

plugins : [PLUGIN.web, PLUGIN.pdf('mistral-ocr')]

('pdf-text' is the free default engine; 'mistral-ocr' handles scanned docs.)


6 · Images & PDFs as input

import {
  attachImageUrl,
  attachPDFBlob,
} from 'ucai-sdk/dist/ucai.esm.js';

/* image url */
await ai.chat({
  messages: [{
    role:'user',
    content:[
      { type:'text', text:"What's in this image?" },
      attachImageUrl('https://example.com/photo.jpg'),
    ],
  }],
});

/* PDF blob (e.g. <input type=file>) */
const pdfPart = await attachPDFBlob(fileInput.files[0]);
await ai.chat({
  messages:[{ role:'user', content:'Summarise this PDF' }],
  files:[pdfPart],
  plugins:[PLUGIN.pdf()],          // use OCR engine if needed
});

7 · Image generation

7.1 URL response (dall-e-2/3)

const res = await ai.generateImage({
  prompt: 'Singapore skyline in synth-wave style',
  model : 'openai/dall-e-3',
  size  : '1024x1024',
});
document.getElementById('out').src = res.data[0].url;   // expires in 60 min

7.2 Base-64 response (gpt-image-1)

const res = await ai.generateImage({
  prompt: 'Cute corgi in space suit',
  model : 'gpt-image-1',
  response_format: 'b64_json',      // default for this model
});

const img = new Image();
img.src = `data:image/png;base64,${res.data[0].b64_json}`;
document.body.append(img);

8 · Helper cheat-sheet

| Helper | Purpose | | ----------------------------------- | --------------------------------- | | attachImageUrl(url) | Image by public URL | | attachImageBlob(blob) | Local file/Blob image | | attachPDFBlob(blob) | Local PDF attachment | | toDataURL(buf,mime) | Low-level base-64 utility | | PLUGIN.web / PLUGIN.pdf(engine) | Plugin presets | | compressSchema(schema) | Minify JSON-schema before sending | | validateAgainst(schema,obj) | Runtime AJV validation (async) |


9 · One-file bundle

npm i            # installs esbuild (dev dep)
npm run build    # → dist/ucai.esm.js & ucai.iife.js

Drop ucai.iife.js into any legacy HTML page:

<script src="ucai.iife.js"></script>
<script>
  const ai = new UCAI.UCAI({ baseUrl:'https://…', apiKey:'sk-…' });
  ai.chat({ messages:[{role:'user', content:'hi'}] }).then(console.log);
</script>

10 · Full demo

demo/demo.js exercises every feature—non-stream, streaming, tools, schema, plugins, multimodal, and image generation.

node demo/demo.js           # needs Node ≥ 18 for global fetch

Enjoy the speed boost—one import, all modern OpenAI goodies.