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

jassie-ai

v1.0.4

Published

Official TypeScript SDK for the Jassie AI API — works with Node.js, React, Next.js, Vue, Angular, Svelte, React Native, and every JS/TS framework

Readme

Jassie AI SDK

npm version npm downloads License: MIT

Official TypeScript SDK for the Jassie AI API — built by Airbin.

Generate text, code, images, videos, music, speech, and real-time voice calls — all from one SDK. Works with Node.js, React, Next.js, Vue, Angular, Svelte, React Native, Deno, Bun, and every JS/TS runtime.

  • Zero runtime dependencies
  • Full TypeScript support with strict types
  • Real-time streaming via Server-Sent Events (SSE)
  • Automatic retries with exponential backoff

Table of Contents


Installation

npm install jassie-ai

Setup

import JassieAI from 'jassie-ai';

const client = new JassieAI({ apiKey: 'your-api-key' });

Text Generation

| Model | Description | |---|---| | jassie-pulse | Lightning-fast text intelligence with million-token context | | jassie-bolt | Flagship multimodal model — text, images, and video input |

// Non-streaming
const response = await client.text.generate({
  model: 'jassie-pulse',
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Explain how DNS works.' },
  ],
  web: 'auto',
});

console.log(response.content);
console.log(response.web_search?.query); // search query, if web search was used

// Streaming
const stream = client.text.generate({
  model: 'jassie-pulse',
  messages: [{ role: 'user', content: 'Write a poem about the ocean.' }],
  stream: true,
});

for await (const chunk of stream) {
  if (chunk.type === 'text') process.stdout.write(chunk.content);
}

Parameters

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | model | 'jassie-pulse' \| 'jassie-bolt' | Yes | — | Model to use | | messages | Message[] | Yes | — | Array of conversation messages | | stream | boolean | No | false | Enable real-time streaming | | maxTokens | number | No | 5000 | Maximum tokens in the response | | temperature | number | No | 0.7 | Randomness (0 = deterministic, 2 = creative) | | web | 'auto' \| 'always' \| null | No | null | Web search mode |

Message format: { role: 'system' | 'user' | 'assistant', content: string, image?: string | string[], video?: string | string[] }

Note: The image and video fields are only supported by jassie-bolt. Pulse is a text-only model.

Vision (Bolt only)

jassie-bolt can analyze images and videos passed in messages.

// Single image
const response = await client.text.generate({
  model: 'jassie-bolt',
  messages: [
    {
      role: 'user',
      content: 'Describe this image.',
      image: 'https://example.com/photo.jpg',
    },
  ],
});

// Multiple images
const response = await client.text.generate({
  model: 'jassie-bolt',
  messages: [
    {
      role: 'user',
      content: 'Compare these two images.',
      image: ['https://example.com/a.jpg', 'https://example.com/b.jpg'],
    },
  ],
});

// Video
const response = await client.text.generate({
  model: 'jassie-bolt',
  messages: [
    {
      role: 'user',
      content: 'What is happening in this video?',
      video: 'https://example.com/clip.mp4',
    },
  ],
});

Response (non-streaming)

| Field | Type | Description | |---|---|---| | type | 'text' \| 'error' | Response type | | content | string | The generated text | | index | number | Output index (starting at 0) | | request_id | string | Unique identifier for the request | | chunks | number | Total number of tokens generated | | duration_seconds | number | Time in seconds the model took to generate the response | | web_search | { query: string } | Present when a web search was performed |


Code Generation

| Model | Description | |---|---| | jassie-code | Writes, refactors, and debugs across dozens of languages |

const response = await client.code.generate({
  model: 'jassie-code',
  messages: [{ role: 'user', content: 'Write a function to reverse a linked list in Python.' }],
});

console.log(response.content);

// With web search for up-to-date APIs
const response = await client.code.generate({
  model: 'jassie-code',
  messages: [{ role: 'user', content: 'Show me how to use the latest Bun.serve() API.' }],
  web: 'auto',
});

Same parameters and response format as Text Generation.


Image Generation

| Model | Description | |---|---| | jassie-pixel | Photorealistic 2K image generation | | jassie-pixel-x | 4K ultra-high-resolution image generation |

Two modes: v1 (synchronous) blocks until done, v2 (asynchronous) returns a taskId immediately.

// v1 — Synchronous (blocks until image is ready)
const result = await client.image.generate({
  model: 'jassie-pixel',
  prompt: 'A sunset over mountains, digital art style',
});
console.log(result.imageUrl);

// v2 — Asynchronous (returns immediately)
const task = await client.image.generateAsync({
  model: 'jassie-pixel-x',
  prompt: 'A futuristic cityscape at night',
  aspectRatio: '16:9',
});

// Check status (single check)
const status = await client.image.status(task.taskId);

// Or poll until done
const final = await client.image.status(task.taskId, {
  interval: 3000,
  timeout: 120000,
  onPoll: (res) => console.log(res.status),
});

// Or stream live updates (SSE)
const stream = client.image.statusStream(task.taskId);
for await (const event of stream) {
  if (event.type === 'preview') console.log('Preview:', event.imageUrl);
  if (event.type === 'completed') console.log('Done:', event.imageUrl);
  if (event.type === 'failed') console.error('Failed:', event.error);
}

Parameters

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | model | 'jassie-pixel' \| 'jassie-pixel-x' | Yes | — | Model (pixel = 2K, pixel-x = 4K) | | prompt | string | Yes | — | Image description | | image | string \| string[] | No | — | Input image URL(s) for editing or composition (up to 14) | | aspectRatio | string | No | '1:1' | '1:1', '4:3', '3:4', '16:9', '9:16', '3:2', '2:3', '21:9' |

Response

| Field | Type | Description | |---|---|---| | model | string | Model used | | taskId | string | Unique task identifier | | status | 'pending' \| 'preview_ready' \| 'succeeded' \| 'failed' | Current status | | imageUrl | string \| null | URL to generated image (when succeeded) | | expiresOn | string \| null | When the image URL expires |

Stream Events

| Type | Fields | Description | |---|---|---| | status | model, taskId, status | Status changed (pending / preview_ready) | | preview | model, taskId, imageUrl | Base64 preview available | | completed | model, taskId, imageUrl, expiresOn | Final hosted URL ready | | failed | model, taskId, error | Generation failed |


Video Generation

| Model | Description | |---|---| | jassie-vibe | 720p HD video generation | | jassie-motion | 1080p Full-HD video generation | | jassie-cinema | 1080p cinematic video generation with multimodal references |

Video generation is asynchronousgenerate() returns a taskId immediately.

Vibe & Motion

const task = await client.video.generate({
  model: 'jassie-vibe',
  prompt: 'A calm ocean wave crashing on a sandy beach',
  duration: 5,
  aspectRatio: '16:9',
});

const result = await client.video.status(task.taskId);
if (result.status === 'succeeded') console.log(result.videoUrl);

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | model | 'jassie-vibe' \| 'jassie-motion' | Yes | — | Model (vibe = 720p, motion = 1080p) | | prompt | string | Yes | — | Video description | | duration | number | No | 5 | Duration in seconds | | references | Reference[] | No | — | Reference(s) for style guidance. Mutually exclusive with firstFrame/lastFrame. | | firstFrame | string | No | — | Starting frame image URL | | lastFrame | string | No | — | Ending frame image URL | | aspectRatio | string | No | '16:9' | '16:9', '4:3', '1:1', '3:4', '9:16', '21:9', 'adaptive' |

Cinema

jassie-cinema supports multimodal references — pass images, videos, and audio clips to guide generation. Up to 9 images, 3 videos, and 3 audio clips per request.

// Text-to-video
const task = await client.video.generate({
  model: 'jassie-cinema',
  prompt: 'A cinematic drone shot over a mountain range at golden hour',
  duration: 10,
  aspectRatio: '21:9',
});

// With multimodal references
const task = await client.video.generate({
  model: 'jassie-cinema',
  prompt: 'First-person POV product ad. Opening frame is Image 1, use Video 1 for camera framing, Audio 1 as background music.',
  duration: 11,
  aspectRatio: '16:9',
  references: [
    { type: 'image', url: 'https://example.com/product-shot.jpg' },
    { type: 'image', url: 'https://example.com/brand-logo.jpg' },
    { type: 'video', url: 'https://example.com/camera-reference.mp4' },
    { type: 'audio', url: 'https://example.com/background-music.mp3' },
  ],
});

const result = await client.video.status(task.taskId);
if (result.status === 'succeeded') console.log(result.videoUrl);

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | model | 'jassie-cinema' | Yes | — | Cinema model (1080p) | | prompt | string | Yes | — | Video description | | duration | number | No | 5 | Duration in seconds (up to 15) | | references | Reference[] | No | — | Multimodal references (see below) | | aspectRatio | string | No | '16:9' | '21:9', '16:9', '4:3', '1:1', '3:4', '9:16' |

Reference: { type: 'image' | 'video' | 'audio', url: string }

Response

| Field | Type | Description | |---|---|---| | model | string | Model used | | taskId | string | Unique task identifier | | status | 'pending' \| 'running' \| 'succeeded' \| 'failed' | Current status | | videoUrl | string \| null | URL to generated video (when succeeded) | | expiresOn | string \| null | When the video URL expires |

Polling Options

Pass to status() to auto-poll until terminal state:

| Parameter | Type | Default | Description | |---|---|---|---| | interval | number | 5000 | Milliseconds between checks | | timeout | number | 600000 | Max wait time in ms | | onPoll | (response) => void | — | Callback on each poll |

Polling options work the same for image.status(), video.status(), and music.status().


Music Generation

| Model | Description | |---|---| | jassie-beat | AI music generation — vocal or instrumental |

Music generation is asynchronous — same pattern as video.

const task = await client.music.generate({
  model: 'jassie-beat',
  tags: 'pop, upbeat, female vocals',
  lyrics: 'Calm and peaceful, floating through the night\nStars above are shining bright',
  duration: 30,
  seed: 42,
});

const result = await client.music.status(task.taskId);
if (result.status === 'completed') console.log(result.musicUrl);

Parameters

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | model | 'jassie-beat' | Yes | — | Model to use | | tags | string | Yes | — | Comma-separated genre/style tags (e.g. 'lo-fi, chill, piano') | | duration | number | Yes | — | Duration in seconds (5–240) | | lyrics | string | No | — | Song lyrics. Omit for instrumental. | | seed | number | No | Random | Seed for reproducible results |

Response

| Field | Type | Description | |---|---|---| | model | string | Model used | | taskId | string | Unique task identifier | | status | 'pending' \| 'processing' \| 'completed' \| 'failed' | Current status | | musicUrl | string \| null | URL to generated audio (when completed) | | expiresOn | string \| null | When the audio URL expires |


Voice (TTS, STT & Voice Call)

| Model | Description | |---|---| | jassie-voice | Text-to-speech, speech-to-text, and real-time voice call. Uses VoiceDesign — describe any voice via the instruct parameter. |

Text to Speech

Returns Promise<ArrayBuffer> — raw audio bytes (MP3).

The voice is controlled entirely through the instruct parameter. Describe the voice you want — gender, tone, accent, pacing, emotion — and the model generates it.

const audio = await client.voice.tts({
  model: 'jassie-voice',
  text: 'Hello, how are you?',
  instruct: 'A warm male voice with an American accent, speaking in a friendly tone',
  seed: 42,
});

// Save to file (Node.js)
import fs from 'fs';
fs.writeFileSync('hello.mp3', Buffer.from(audio));

| Parameter | Type | Required | Default | Description | |---|---|---|---|---| | model | 'jassie-voice' | Yes | — | Model to use | | text | string | Yes | — | Text to speak (max 5000 chars) | | instruct | string | No | — | Voice and style description (e.g. "A calm female voice with a British accent") | | seed | number | No | 42 | Random seed for voice consistency. Same seed + same instruct = consistent voice. |

Speech to Text

Returns Promise<string> — transcribed text. Language is auto-detected.

const text = await client.voice.stt({
  model: 'jassie-voice',
  file: audioBlob,   // webm, mp3, wav, ogg, etc. (max 25MB)
});

| Parameter | Type | Required | Description | |---|---|---|---| | model | 'jassie-voice' | Yes | Model to use | | file | Blob \| File | Yes | Audio file to transcribe |

Voice Call (Real-time Chat)

Send audio and get a streamed response with both text and audio. Under the hood, this combines three models in a single pipeline: Jassie STT transcribes the user's audio, Jassie Pulse (with web search set to auto) generates the response, and Jassie TTS synthesizes the reply into streamed speech. Returns a VoiceChatStream — an async iterable of events.

Audio is streamed as raw PCM int16 chunks for low-latency playback. Each sentence produces an audio_start event, followed by one or more audio_chunk events containing base64-encoded PCM data, and finally an audio_end event. The legacy audio event (complete base64 MP3 per sentence) may appear as a fallback.

const stream = client.voice.chat({
  audio: audioBlob,              // recorded audio (webm, mp3, wav, etc.)
  messages: [                    // optional: conversation history
    { role: 'user', content: 'Hello, how are you?' },
  ],
  instruct: 'A calm, reassuring male voice',  // optional: voice description
  seed: 42,                      // optional: consistent voice across calls
});

// Option 1: iterate events
for await (const event of stream) {
  if (event.type === 'text_chunk') process.stdout.write(event.text_chunk);
  if (event.type === 'audio_start') console.log('Playing:', event.sentence);
  if (event.type === 'audio_chunk') playPCMChunk(event.audio_chunk); // base64 PCM int16
  if (event.type === 'audio_end') console.log('Sentence done');
  if (event.type === 'done') console.log('\nFull response:', event.text);
}

// Option 2: callback
await stream.eachEvent((event) => {
  if (event.type === 'text_chunk') process.stdout.write(event.text_chunk);
});

// Option 3: collect final result
const result = await stream.finalResult();
console.log(result.text);       // full response text
console.log(result.user_text);  // transcribed user audio

// Abort anytime
stream.abort();

| Parameter | Type | Required | Description | |---|---|---|---| | audio | Blob \| File | Yes | Recorded audio to send | | messages | { role: string, content: string }[] | No | Conversation history for context | | instruct | string | No | Voice and style description (e.g. "A warm female voice with a British accent") | | seed | number | No | Random seed for voice consistency (default: 42) |

Voice Chat Event Types

| Type | Fields | Description | |---|---|---| | searching | — | Server is performing a web search | | text_chunk | text_chunk | Partial text being generated | | audio_start | sentence, sample_rate | Marks the beginning of a sentence's streamed audio (PCM int16, typically 24000 Hz) | | audio_chunk | audio_chunk | Base64-encoded PCM int16 audio data | | audio_end | sentence | Marks the end of a sentence's streamed audio | | audio | audio, sentence | Fallback: complete base64-encoded MP3 audio for a sentence | | done | text, user_text | Stream complete — full response text and transcribed user audio | | error | error | Error message |

Voice Chat Stream Methods

| Method | Returns | Description | |---|---|---| | eachEvent(cb) | Promise<void> | Calls cb(event) for each event | | finalResult() | Promise<VoiceChatEvent \| null> | Returns the done event | | abort() | void | Cancels the stream |


Error Handling

All errors extend JassieError. The SDK auto-retries on 5xx, 429, network errors, and timeouts with exponential backoff.

import JassieAI, {
  JassieAuthenticationError, // 401
  JassieRateLimitError,      // 429 — has retryAfter field
  JassieAPIError,            // 4xx / 5xx
  JassieTimeoutError,        // timeout exceeded
  JassieConnectionError,     // network failure
} from 'jassie-ai';

try {
  const response = await client.text.generate({ ... });
} catch (error) {
  if (error instanceof JassieRateLimitError) {
    console.error('Retry after:', error.retryAfter, 'seconds');
  } else if (error instanceof JassieAPIError) {
    console.error(`API error ${error.status}: ${error.message}`);
  }
}

React Native

The SDK auto-detects React Native and uses XMLHttpRequest for streaming. Hermes does not support for await...of — use eachText() instead:

import JassieAI from 'jassie-ai';
const client = new JassieAI({ apiKey: 'your-api-key' });

// Text streaming
const stream = client.text.generate({
  model: 'jassie-pulse',
  messages: [{ role: 'user', content: 'Hello from React Native!' }],
  stream: true,
});

await stream.eachText((text) => {
  setResponse((prev) => prev + text);
});

// Image streaming
const task = await client.image.generateAsync({
  model: 'jassie-pixel',
  prompt: 'A sunset over mountains',
});

const imgStream = client.image.statusStream(task.taskId);
await imgStream.eachEvent((event) => {
  if (event.type === 'preview') setPreview(event.imageUrl);
  if (event.type === 'completed') setFinalUrl(event.imageUrl);
});

// Voice call streaming
const voiceStream = client.voice.chat({
  audio: audioBlob,
  instruct: 'A friendly, natural male voice',
});

await voiceStream.eachEvent((event) => {
  if (event.type === 'text_chunk') setText((prev) => prev + event.text_chunk);
  if (event.type === 'audio_start') console.log('Playing:', event.sentence);
  if (event.type === 'audio_chunk') playPCMChunk(event.audio_chunk);
  if (event.type === 'done') console.log('Done:', event.text);
});

Aborting

const streamRef = useRef<{ abort: () => void } | null>(null);

const send = async (prompt: string) => {
  const stream = client.text.generate({
    model: 'jassie-pulse',
    messages: [{ role: 'user', content: prompt }],
    stream: true,
  });
  streamRef.current = stream;
  await stream.eachText((text) => setResponse((prev) => prev + text));
  streamRef.current = null;
};

const stop = () => streamRef.current?.abort();

About

Jassie AI is developed and maintained by Airbin.

Website: airbin.app | API Docs: jassie.ai


License

MIT