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

@smarthivelabs-devs/ai-nexus

v1.0.0

Published

Official Node.js SDK for the SmartHive AI Nexus API

Readme

@smarthivelabs-devs/ai-nexus

Official Node.js / TypeScript SDK for the SmartHive AI Nexus — a unified AI gateway that routes requests to OpenAI, Anthropic, Gemini, ElevenLabs, FAL, Stability, and Runway through a single API.

What this package is: The foundation SDK. Zero runtime dependencies, works in Node.js 18+, edge runtimes, and any bundler. Every other SmartHive SDK (react-ai-nexus, next-ai-nexus, ai-nexus-expo) builds on top of this one.


Features

  • Zero runtime dependencies — uses the platform fetch API (Node 18+, Deno, Bun, edge runtimes)
  • Dual ESM + CJSimport and require both work, correct types for both
  • 40+ fully typed interfaces — every request param and response field has a TypeScript type
  • Automatic retries — exponential backoff on 408, 429, 500, 502, 503, 504 (capped at 8 s)
  • Per-request timeoutsAbortController-based, configurable per client or per request
  • Streaming — type-safe AsyncIterable<ChatStreamChunk> via function overloads; no extra setup
  • Structured error hierarchy — catch AiNexusAuthError, AiNexusRateLimitError, etc. individually

Installation

npm install @smarthivelabs-devs/ai-nexus
# or
yarn add @smarthivelabs-devs/ai-nexus
# or
pnpm add @smarthivelabs-devs/ai-nexus

Node.js ≥ 18 is required (uses native fetch).


Environment Setup

Create a .env file (or set these in your hosting platform):

# Required — your API key from the SmartHive AI Nexus dashboard
AI_NEXUS_API_KEY=nexus_live_xxxxxxxxxxxxxxxxxxxx

# Optional — only needed if self-hosting or pointing at a staging environment
# Default: https://api.smarthivelabs.dev
AI_NEXUS_BASE_URL=https://api.smarthivelabs.dev

The SDK does not read env vars automatically. You must pass apiKey explicitly:

const nexus = new AiNexus({ apiKey: process.env.AI_NEXUS_API_KEY! });

Quick Start

import { AiNexus } from '@smarthivelabs-devs/ai-nexus';

const nexus = new AiNexus({
  apiKey: process.env.AI_NEXUS_API_KEY!,
});

// Blocking chat
const response = await nexus.chat.create({
  model: 'claude-sonnet-4-6',
  messages: [{ role: 'user', content: 'Hello!' }],
});
console.log(response.choices[0]?.message.content);

Client Configuration

const nexus = new AiNexus({
  apiKey: 'nexus_live_xxx',     // Required. API key from the dashboard.
  baseUrl: 'https://...',       // Optional. Default: https://api.smarthivelabs.dev
  maxRetries: 2,                // Optional. Default: 2. Set to 0 to disable retries.
  timeout: 30_000,              // Optional. Default: 30 000 ms (30 s).
  defaultHeaders: {             // Optional. Extra headers sent on every request.
    'X-Project-ID': 'proj_123',
  },
});

Per-request overrides

withOptions() returns a new client with overridden settings — the original is unchanged:

// This request uses a 5 s timeout; the original client is unaffected
const response = await nexus
  .withOptions({ timeout: 5_000 })
  .chat.create({ model: 'gpt-4o', messages: [...] });

// Different API key for a different project
const projectClient = nexus.withOptions({ apiKey: 'nexus_live_project_b' });

Resources

nexus.chat — Chat Completions

Send messages to any supported LLM (OpenAI GPT-4o, Claude, Gemini, etc.). The model name is routed through your configured model profiles.

// Blocking response
const res = await nexus.chat.create({
  model: 'gpt-4o',
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Explain async/await in one paragraph.' },
  ],
  temperature: 0.7,        // 0–2, controls randomness
  max_tokens: 512,         // cap the response length
  top_p: 0.95,             // nucleus sampling
  stop: ['\n\n'],          // stop sequence
  n: 1,                    // number of completions
  user: 'user_abc123',     // end-user ID for abuse tracking
  response_format: { type: 'json_object' },  // force JSON output
});

console.log(res.choices[0]?.message.content);
console.log(`Tokens used: ${res.usage.total_tokens}`);

Streamingstream: true narrows the return type to Promise<AsyncIterable<ChatStreamChunk>> at compile time:

const stream = await nexus.chat.create({
  model: 'claude-sonnet-4-6',
  messages: [{ role: 'user', content: 'Write me a poem.' }],
  stream: true,
});

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

Vision (multimodal) — pass image URLs alongside text:

await nexus.chat.create({
  model: 'gpt-4o',
  messages: [{
    role: 'user',
    content: [
      { type: 'image_url', image_url: { url: 'https://example.com/diagram.png', detail: 'high' } },
      { type: 'text', text: 'What does this diagram show?' },
    ],
  }],
});

Tool / function calling:

const res = await nexus.chat.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'What is the weather in London?' }],
  tools: [{
    type: 'function',
    function: {
      name: 'get_weather',
      description: 'Get current weather for a city',
      parameters: {
        type: 'object',
        properties: {
          city: { type: 'string' },
          unit: { type: 'string', enum: ['celsius', 'fahrenheit'] },
        },
        required: ['city'],
      },
    },
  }],
  tool_choice: 'auto',
});

if (res.choices[0]?.finish_reason === 'tool_calls') {
  const call = res.choices[0].message.tool_calls?.[0];
  const args = JSON.parse(call?.function.arguments ?? '{}');
  // { city: 'London' }
}

Multi-turn conversation:

const messages: ChatMessage[] = [];

messages.push({ role: 'user', content: 'My name is Alex.' });
const r1 = await nexus.chat.create({ model: 'gpt-4o', messages });
messages.push(r1.choices[0]!.message);

messages.push({ role: 'user', content: 'What is my name?' });
const r2 = await nexus.chat.create({ model: 'gpt-4o', messages });
console.log(r2.choices[0]?.message.content); // "Your name is Alex."

nexus.embeddings — Vector Embeddings

Generate embeddings for semantic search, clustering, and similarity matching.

const res = await nexus.embeddings.create({
  model: 'text-embedding-3-large',
  input: ['Hello world', 'Bonjour le monde'],
  dimensions: 1024,        // optional — reduce dimensions for storage
  encoding_format: 'float', // 'float' (default) or 'base64'
});

// res.data[0].embedding → number[] of length 1024
const similarity = cosineSimilarity(res.data[0]!.embedding, res.data[1]!.embedding);

Single string input also works:

const res = await nexus.embeddings.create({
  model: 'text-embedding-3-small',
  input: 'Query text for search',
});

nexus.audio — Speech-to-Text and Text-to-Speech

Transcribe audio → text (Whisper):

const transcript = await nexus.audio.transcribe({
  audioUrl: 'https://storage.example.com/recording.mp3', // public or pre-signed URL
  model: 'whisper-large-v3',   // optional, uses your default model profile
  language: 'en',              // optional BCP-47 code, improves accuracy
  prompt: 'SmartHive, API',    // optional vocabulary hint
  response_format: 'json',     // 'json' | 'text' | 'srt' | 'vtt'
  temperature: 0,              // 0 = deterministic
});

console.log(transcript.text);
console.log(transcript.segments); // timestamped word-level segments

Synthesize text → speech (TTS):

const audio = await nexus.audio.speak({
  text: 'Welcome to SmartHive AI Nexus.',
  model: 'tts-1-hd',      // optional — 'tts-1' (fast) or 'tts-1-hd' (quality)
  voiceProfile: 'nova',   // optional — voice name from your provider
  speed: 1.0,             // optional — 0.25–4.0
  response_format: 'mp3', // optional — 'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm'
});

// audio.data → ArrayBuffer
// audio.contentType → 'audio/mpeg'

// Node.js — save to file
import { writeFileSync } from 'fs';
writeFileSync('speech.mp3', Buffer.from(audio.data));

// Browser — create a download
const blob = new Blob([audio.data], { type: audio.contentType });
const url = URL.createObjectURL(blob);

nexus.images — Image Generation

Image generation is async (the provider processes it as a job). Poll until complete.

// Start the job
const job = await nexus.images.generate({
  prompt: 'A futuristic city skyline at sunset, photorealistic',
  model: 'dall-e-3',             // optional — uses default image model
  size: '1024x1024',             // '256x256' | '512x512' | '1024x1024' | '1024x1792' | '1792x1024'
  quality: 'hd',                 // 'standard' | 'hd'
  style: 'vivid',                // 'vivid' | 'natural'
  n: 1,                          // number of images
  response_format: 'url',        // 'url' | 'b64_json'
});

// Poll until done (or use useImages hook in React)
let result = await nexus.images.getJob(job.jobId);
while (result.status === 'queued' || result.status === 'processing') {
  await new Promise(r => setTimeout(r, 2_000));
  result = await nexus.images.getJob(job.jobId);
}

if (result.status === 'completed') {
  console.log(result.data?.[0]?.url);
} else {
  console.error('Generation failed:', result.error);
}

nexus.videos — Video Generation

Same async job pattern as images, but may take 1–5 minutes to complete.

// Start generation
const job = await nexus.videos.generate({
  prompt: 'A timelapse of clouds over mountains',
  model: 'runway-gen3',      // optional
  duration: 5,               // seconds (provider-dependent max)
  aspectRatio: '16:9',       // '16:9' | '9:16' | '1:1' | '4:3'
  quality: 'hd',             // 'standard' | 'hd'
  style: 'cinematic',        // optional style hint
});

// Poll
let result = await nexus.videos.getJob(job.jobId);
while (result.status === 'queued' || result.status === 'processing') {
  await new Promise(r => setTimeout(r, 10_000));
  result = await nexus.videos.getJob(job.jobId);
}

console.log(result.url);           // video URL
console.log(result.thumbnailUrl);  // thumbnail
console.log(result.duration);      // actual duration in seconds

// List all video jobs
const all = await nexus.videos.listJobs();
console.log(`${all.total} total jobs`);

nexus.agents — AI Agents

Run an agent by its ID. The agent uses its configured system prompt, model, and knowledge base.

// Single-turn
const res = await nexus.agents.run({
  agentId: 'agent_abc123',
  input: 'Summarise our Q1 sales report.',
  context: { userId: 'user_456', tier: 'premium' }, // optional metadata
});

console.log(res.output);
console.log(res.sessionId);      // save this for multi-turn
console.log(res.finishReason);   // 'stop' | 'tool_calls' | 'length'
console.log(res.usage?.total_tokens);

Multi-turn with session continuity:

// Turn 1
const turn1 = await nexus.agents.run({
  agentId: 'agent_abc123',
  input: 'I need help with my order #ORD-9988.',
});

// Turn 2 — pass sessionId to maintain conversation history
const turn2 = await nexus.agents.run({
  agentId: 'agent_abc123',
  input: 'What is its current status?',
  sessionId: turn1.sessionId,  // links turns together
});

// Retrieve full session history
const session = await nexus.agents.getSession(turn1.sessionId);
console.log(session.messages);  // full conversation
console.log(session.status);    // 'active' | 'ended'

nexus.realtime — Realtime Voice Sessions

Create a LiveKit WebRTC session for real-time voice conversations with an agent.

import { Room } from 'livekit-client';

// 1. Create the session
const session = await nexus.realtime.sessions.create({
  agentId: 'agent_abc123',
  mode: 'voice',                   // 'voice' | 'text' | 'duplex'
  features: ['transcription', 'tts', 'vad', 'recording'],
  metadata: { userId: 'user_789' }, // optional
});

// session.livekitUrl   → wss://your-livekit-server.livekit.cloud
// session.livekitToken → JWT for this participant
// session.sessionId    → use for all subsequent calls

// 2. Connect to LiveKit with the returned credentials
const room = new Room();
await room.connect(session.livekitUrl, session.livekitToken);

// 3. Poll for transcript updates
const detail = await nexus.realtime.sessions.get(session.sessionId);
for (const entry of detail.transcript ?? []) {
  console.log(`${entry.role}: ${entry.text}`);
}

// 4. Recording
const rec = await nexus.realtime.sessions.startRecording(session.sessionId);
console.log(rec.recordingId);

const stopped = await nexus.realtime.sessions.stopRecording(session.sessionId, {
  format: 'mp4',   // 'mp4' | 'webm' | 'mp3'
});
console.log(stopped.url);       // download URL
console.log(stopped.duration);  // seconds
console.log(stopped.size);      // bytes

// 5. End the session
await nexus.realtime.sessions.end(session.sessionId);

nexus.documents — Knowledge Base Documents

Ingest documents into a knowledge base for RAG (retrieval-augmented generation).

// Ingest a document by URL
const doc = await nexus.documents.ingest({
  storageUrl: 'https://storage.example.com/policy.pdf',  // public or pre-signed
  knowledgeBaseId: 'kb_xyz789',    // which knowledge base to add it to
  metadata: { department: 'legal', version: '2026-Q1' },
  chunkSize: 512,      // optional — tokens per chunk
  chunkOverlap: 64,    // optional — overlap between chunks
});

// doc.status → 'queued' | 'processing' | 'completed' | 'failed'
// doc.documentId → use to check status

// Check processing status
let detail = await nexus.documents.get(doc.documentId);
while (detail.status === 'queued' || detail.status === 'processing') {
  await new Promise(r => setTimeout(r, 3_000));
  detail = await nexus.documents.get(doc.documentId);
}
console.log(`Chunks created: ${detail.chunkCount}`);

// List documents in a knowledge base
const list = await nexus.documents.list({
  knowledgeBaseId: 'kb_xyz789',
  page: 1,
  pageSize: 20,
});
console.log(`${list.total} documents`);

// Delete a document
await nexus.documents.delete(doc.documentId);

nexus.retrieval — Semantic Search

Query a knowledge base by semantic similarity. Used internally by RAG-enabled agents and useChat.

const results = await nexus.retrieval.query({
  query: 'What is the refund window for digital products?',
  knowledgeBaseId: 'kb_xyz789',
  topK: 5,         // number of results to return
  minScore: 0.7,   // optional — minimum similarity score (0–1)
  filter: { department: 'legal' },  // optional metadata filter
});

for (const r of results.results) {
  console.log(`[${r.score.toFixed(3)}] ${r.content}`);
  console.log(`  documentId: ${r.documentId}, chunkId: ${r.chunkId}`);
}

nexus.moderation — Content Moderation

Check text or images for policy violations before processing.

// Text moderation
const result = await nexus.moderation.moderate({
  input: 'User submitted message here',
  model: 'omni-moderation-latest',  // optional
});

if (result.flagged) {
  // result.categories contains per-category scores
  const flaggedCategories = Object.entries(result.categories)
    .filter(([, v]) => v?.flagged)
    .map(([k]) => k);
  console.log('Blocked — flagged for:', flaggedCategories.join(', '));
}

// Image moderation
const imgResult = await nexus.moderation.moderate({
  imageUrl: 'https://example.com/user-upload.jpg',
});

Available categories: hate, hate/threatening, harassment, harassment/threatening, self-harm, self-harm/intent, self-harm/instructions, sexual, sexual/minors, violence, violence/graphic.


nexus.models — Model Profiles

List available models and their capabilities.

// List all active model profiles
const models = await nexus.models.list();
for (const model of models) {
  console.log(`${model.slug} (${model.provider}) — ${model.capabilities.join(', ')}`);
  console.log(`  context: ${model.contextWindow}, cost: $${model.inputCostPer1k}/1k in`);
}

// Get a specific model
const model = await nexus.models.get('claude-sonnet-4-6');
console.log(model.maxOutputTokens);
console.log(model.isAvailable);

nexus.usage — Usage & Cost Tracking

Query usage events for billing, analytics, or project cost tracking.

const report = await nexus.usage.list({
  startDate: '2026-01-01',   // ISO 8601 date
  endDate: '2026-01-31',
  projectId: 'proj_abc',     // optional — filter by project
  modelSlug: 'gpt-4o',       // optional — filter by model
  page: 1,
  pageSize: 100,
});

console.log(`Total requests: ${report.summary.totalRequests}`);
console.log(`Total tokens: ${report.summary.totalTokens}`);
console.log(`Total cost: $${report.summary.totalCostUsd.toFixed(4)}`);

for (const event of report.data) {
  console.log(`${event.createdAt} | ${event.modelSlug} | ${event.capability} | ${event.totalTokens} tokens | $${event.costUsd}`);
}

nexus.health — Health Check

No authentication required. Use this to verify connectivity before making API calls.

const health = await nexus.health.check();
// { status: 'ok' | 'degraded' | 'down', version: '1.2.3', uptime: 99.97, timestamp: '...' }

if (health.status !== 'ok') {
  console.warn('AI Nexus is degraded:', health.services);
}

Error Handling

Every error thrown by the SDK extends AiNexusError. Import the specific classes to catch only what you care about:

import {
  AiNexusError,
  AiNexusAPIError,
  AiNexusAuthError,
  AiNexusRateLimitError,
  AiNexusConnectionError,
  AiNexusTimeoutError,
} from '@smarthivelabs-devs/ai-nexus';

try {
  const res = await nexus.chat.create({ model: 'gpt-4o', messages });
} catch (err) {
  if (err instanceof AiNexusAuthError) {
    // HTTP 401 or 403 — invalid or expired API key
    console.error('Invalid API key. Check AI_NEXUS_API_KEY.');

  } else if (err instanceof AiNexusRateLimitError) {
    // HTTP 429 — too many requests
    console.error(`Rate limited. Retry after ${err.retryAfter ?? 'unknown'} seconds.`);

  } else if (err instanceof AiNexusTimeoutError) {
    // Request exceeded the configured timeout
    console.error('Request timed out. Increase timeout or retry.');

  } else if (err instanceof AiNexusConnectionError) {
    // Network failure — no response received
    console.error('Cannot reach AI Nexus. Check your network.');

  } else if (err instanceof AiNexusAPIError) {
    // Any other non-2xx HTTP response
    console.error(`API error ${err.status}: ${err.message}`);
    console.error('Code:', err.code);
    console.error('Request ID:', err.requestId);

  } else if (err instanceof AiNexusError) {
    // All other SDK errors
    console.error('SDK error:', err.message);
  }
}

Error Hierarchy

AiNexusError                       — base class for all SDK errors
  ├─ AiNexusAPIError               — non-2xx response (has .status, .code, .requestId)
  │   ├─ AiNexusAuthError          — HTTP 401 or 403
  │   └─ AiNexusRateLimitError     — HTTP 429 (has .retryAfter in seconds)
  └─ AiNexusConnectionError        — no response received (network failure)
      └─ AiNexusTimeoutError       — request exceeded configured timeout

Automatic Retries

The SDK retries on 408, 429, 500, 502, 503, 504 with exponential backoff:

| Attempt | Delay | |---------|-------| | 1st retry | 500 ms | | 2nd retry | 1 000 ms | | (capped at 8 000 ms) |

Configure with maxRetries: 0 to disable, or maxRetries: 5 for more resilience.


TypeScript

The SDK ships with .d.ts declaration files and source maps. All types are exported:

import type {
  // Client
  AiNexusClientOptions,

  // Chat
  ChatMessage, ChatTool, ToolCall, ContentPart,
  ChatCreateParams, ChatCreateParamsStream,
  ChatResponse, ChatStreamChunk, ChatUsage,

  // Embeddings
  EmbeddingsCreateParams, EmbeddingsResponse, EmbeddingObject,

  // Audio
  AudioTranscribeParams, AudioTranscribeResponse,
  AudioSpeakParams, AudioSpeakResponse,

  // Images
  ImagesGenerateParams, ImagesGenerateResponse, ImageJob, ImageObject,

  // Videos
  VideosGenerateParams, VideoJob, VideoJobsListResponse,

  // Agents
  AgentsRunParams, AgentsRunParamsStream, AgentsRunResponse, AgentSession,

  // Realtime
  RealtimeCreateSessionParams, RealtimeSessionResponse, RealtimeSessionDetail,
  RealtimeMode, RealtimeFeature,
  RecordingStartResponse, RecordingStopParams, RecordingStopResponse,

  // Documents
  DocumentsIngestParams, DocumentIngestResponse, DocumentDetail, DocumentsListParams,

  // Retrieval
  RetrievalQueryParams, RetrievalQueryResponse, RetrievalResult,

  // Moderation
  ModerationParams, ModerationResponse, ModerationCategory,

  // Models
  ModelProfile, ModelCapability,

  // Usage
  UsageListParams, UsageListResponse, UsageEvent,

  // Health
  HealthResponse,
} from '@smarthivelabs-devs/ai-nexus';

CommonJS

const { AiNexus, AiNexusAuthError } = require('@smarthivelabs-devs/ai-nexus');
const nexus = new AiNexus({ apiKey: process.env.AI_NEXUS_API_KEY });

License

MIT — © SmartHive Labs