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

oblien

v1.1.0

Published

Server-side SDK for Oblien AI Platform - Build AI-powered applications with chat, agents, and workflows

Downloads

856

Readme

Oblien Core SDK

Server-side SDK for building AI-powered applications with Oblien platform.

Features

  • 🔐 Direct header authentication - Uses x-client-id and x-client-secret headers
  • 👤 Dual-layer guest identification - IP + fingerprint for better guest tracking
  • 🔄 Smart guest matching - Detects same guest even when IP or fingerprint changes
  • 📊 Namespace management - Multi-tenant workspaces with service configurations
  • Automatic rate limiting - Built-in limits for guest sessions
  • 💾 Flexible storage - NodeCache (default), Redis, or custom adapters
  • 🎯 Complete usage tracking - Monitor credits, quotas, and activity

Installation

npm install oblien

What This SDK Does

Server-Side Only - This SDK is for creating and managing chat sessions on your server. It does not handle actual messaging - that happens client-side in the browser using the tokens this SDK generates.

Workflow:

  1. Server: Create session using this SDK → Get token
  2. Server: Send token to client (browser)
  3. Client: Use token to chat directly with Oblien API
  4. Client: Use react-chat-agent or your own implementation

Quick Start

1. Initialize Client

import { OblienClient } from 'oblien';

const client = new OblienClient({
    apiKey: 'your-client-id',      // Your Oblien Client ID
    apiSecret: 'your-client-secret', // Your Oblien Client Secret (required)
 });

2. Create Chat Session

import { OblienChat } from 'oblien/chat';

const chat = new OblienChat(client);

// Create session for authenticated user
const session = await chat.createSession({
    agentId: 'your-agent-id',
    namespace: 'user_123', // Optional: User ID for rate limiting/tracking
    // workflowId: 'workflow-id', // Optional
    // workspace: {}, // Optional
});

console.log(session);
// {
//   sessionId: 'session-xxx',
//   token: 'jwt-token-for-client',
//   agentId: 'agent-id',
//   namespace: 'user_123'
// }

3. Send Token to Client

// Express example
app.post('/api/create-session', async (req, res) => {
    const session = await chat.createSession({
        agentId: req.body.agentId,
    });

    res.json({
        sessionId: session.sessionId,
        token: session.token, // Client uses this to chat
    });
});

4. Client Uses Token

// In browser (using react-chat-agent)
import { ChatProvider } from 'react-chat-agent';

function App() {
    const [sessionToken, setSessionToken] = useState(null);

    useEffect(() => {
        // Get token from your server
        fetch('/api/create-session', {
            method: 'POST',
            body: JSON.stringify({ agentId: 'agent-id' }),
        })
        .then(r => r.json())
        .then(data => setSessionToken(data.token));
    }, []);

    if (!sessionToken) return <div>Loading...</div>;

    return (
        <ChatProvider token={sessionToken}>
            <ChatPanel />
        </ChatProvider>
    );
}

Guest Sessions (Rate Limited)

For anonymous users, create guest sessions with dual-layer identification using IP + fingerprint:

import { OblienChat } from 'oblien/chat';

const chat = new OblienChat(client);

// Express route
app.post('/api/guest-session', async (req, res) => {
    const ip = req.ip || req.headers['x-forwarded-for'];
    const fingerprint = req.body.fingerprint; // Browser fingerprint

    const session = await chat.createGuestSession({
        ip,
        fingerprint, // NEW: Enables dual-layer identification
        agentId: 'your-agent-id',
        metadata: {
            userAgent: req.headers['user-agent'],
            referrer: req.headers['referer'],
        },
    });

    res.json({
        sessionId: session.sessionId,
        token: session.token,
        guest: session.guest,
        // Guest sessions are rate-limited automatically
    });
});

Guest Features:

  • Dual-layer identification: IP + fingerprint for better guest tracking
  • Smart guest matching: Same guest detected even if IP or fingerprint changes
  • ✅ Automatic rate limiting (100K tokens/day, 50 messages/day)
  • ✅ Privacy-friendly (IP masked, fingerprint hashed)
  • ✅ Auto-expiring sessions (24h TTL)
  • ✅ Built-in caching with node-cache (no Redis required!)
  • ✅ Optional Redis support for distributed systems

How Dual-Layer Identification Works:

The package automatically tracks guests using both IP and fingerprint:

  • Fingerprint changes, IP stays → Same guest detected ✅
  • IP changes, fingerprint stays → Same guest detected ✅
  • Both change → New guest created

This provides better continuity for users on mobile networks or using VPNs.

Namespace Management

Manage multi-tenant workspaces with service configurations, usage tracking, and quotas.

import { OblienNamespaces } from 'oblien/namespaces';

const namespaces = new OblienNamespaces(client);

// Create a namespace
const namespace = await namespaces.create({
    name: 'Production Environment',
    type: 'production',
    metadata: { region: 'us-east-1' },
    tags: ['production', 'critical'],
});

// Configure services
await namespaces.configureService(namespace.id, {
    service: 'ai',
    enabled: true,
    config: { model: 'gpt-4', maxTokens: 4000 },
    rateLimitRequests: 1000,
    rateLimitPeriod: 'hour',
});

// Get usage statistics
const usage = await namespaces.getUsage(namespace.id, { days: 30 });
console.log(usage.summary); // Credits, tokens, requests per service

// List all namespaces
const result = await namespaces.list({
    status: 'active',
    type: 'production',
});

Namespace Features:

  • Full CRUD - Create, read, update, delete namespaces
  • Service configuration - Enable/disable services per namespace
  • Usage tracking - Monitor credits, tokens, and requests
  • Quota management - Set limits per service
  • Activity logging - Complete audit trail
  • Rich metadata - Custom fields and tags

📖 Full Namespaces Documentation

Credits Management

Manage credits, quotas, usage tracking, and purchases.

import { OblienCredits } from 'oblien/credits';

const credits = new OblienCredits(client);

// Get balance
const balance = await credits.getBalance();

// Set namespace quota
await credits.setQuota({
    namespace: 'production',
    service: 'ai',
    quotaLimit: 10000,
    period: 'monthly',
});

// Get usage statistics
const stats = await credits.getUsageStats({ days: 7 });

// Purchase credits
const checkout = await credits.createCheckout({
    packageId: 'pro',
});
console.log('Checkout URL:', checkout.checkoutUrl);

// Get transaction history
const history = await credits.getHistory({
    namespace: 'production',
    service: 'ai',
    limit: 50,
});

Credits Features:

  • Balance management - Check and add credits
  • Quota system - Set limits per namespace and service
  • Usage tracking - Complete transaction history
  • Statistics - Daily/monthly aggregated data
  • Purchase integration - Stripe checkout for buying credits
  • Package management - Predefined credit packages

📖 Full Credits Documentation

Guest Storage Options

Default: NodeCache (Recommended)

Works out of the box - no setup needed:

import { OblienChat } from 'oblien/chat';

const chat = new OblienChat(client);
// Uses NodeCacheStorage by default
// Automatic expiration, memory management, and cleanup

Option 1: Custom NodeCache Settings

import { OblienChat, NodeCacheStorage } from 'oblien/chat';

const storage = new NodeCacheStorage(86400); // 24 hours TTL

const chat = new OblienChat(client, {
    guestStorage: storage,
});

// Get cache stats
console.log(storage.getStats());

Option 2: Redis (For Distributed Systems)

import { createClient } from 'redis';
import { OblienChat, RedisStorage } from 'oblien/chat';

const redis = createClient();
await redis.connect();

const chat = new OblienChat(client, {
    guestStorage: new RedisStorage(redis),
    guestTTL: 86400, // 24 hours
});

Option 3: Simple In-Memory (Dev Only)

import { OblienChat, InMemoryStorage } from 'oblien/chat';

const chat = new OblienChat(client, {
    guestStorage: new InMemoryStorage(),
});
// Note: Basic Map storage, no advanced features

API Reference

OblienClient

Main client for authentication:

const client = new OblienClient({
    apiKey: string,
    apiSecret?: string,
    baseURL?: string,
});

OblienChat

Session management:

const chat = new OblienChat(client, options?);

// Create regular session (authenticated users)
await chat.createSession({ 
    agentId, 
    namespace?, // Optional: user_id for tracking
    workflowId?, 
    workspace? 
});

// Create guest session (with dual-layer identification)
await chat.createGuestSession({ 
    ip, 
    fingerprint?, // NEW: Browser fingerprint for better tracking
    agentId, 
    workflowId?, 
    metadata?, 
    workspace? 
});

// Get session info
await chat.getSession(sessionId);

// List sessions
await chat.listSessions({ page?, limit? });

// Delete session
await chat.deleteSession(sessionId);

// Guest management
await chat.getGuest(ip, fingerprint?); // NEW: Unified function for IP and/or fingerprint lookup
await chat.getAllGuests(); // Admin only
await chat.cleanupGuests(); // Clean expired

GuestManager

Manual guest management:

import { GuestManager } from 'oblien/chat';

const guestManager = new GuestManager({
    storage?: StorageAdapter,
    ttl?: number, // seconds
    onGuestCreated?: (guest) => void,
});

// With dual-layer identification
await guestManager.getOrCreateGuest(ip, fingerprint?, metadata?);

// Find existing guest by IP and/or fingerprint
await guestManager.findExistingGuest(fingerprint, ip);

await guestManager.getGuest(guestId);
await guestManager.updateGuest(guestId, updates);
await guestManager.deleteGuest(guestId);
await guestManager.getAllGuests();
await guestManager.cleanup();

Complete Example

Express Server

import express from 'express';
import { OblienClient, OblienChat } from 'oblien';

const app = express();
app.use(express.json());

// Initialize Oblien
const client = new OblienClient({
    apiKey: process.env.OBLIEN_API_KEY,
    apiSecret: process.env.OBLIEN_API_SECRET,
});

const chat = new OblienChat(client);

// Create authenticated session
app.post('/api/session', async (req, res) => {
    try {
        const session = await chat.createSession({
            agentId: req.body.agentId,
            namespace: req.user.id, // Pass user ID as namespace
        });

        res.json(session);
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

// Create guest session with dual-layer identification
app.post('/api/guest-session', async (req, res) => {
    try {
        const ip = req.ip || req.headers['x-forwarded-for'];
        const fingerprint = req.body.fingerprint; // From client
        
        // Check for existing guest first
        const existingGuest = await chat.getGuest(ip, fingerprint);
        
        if (existingGuest && existingGuest.sessions.length > 0) {
            // Return existing session if available
            const latestSession = existingGuest.sessions[existingGuest.sessions.length - 1];
            const sessionDetails = await chat.getSession(latestSession);
            
            if (sessionDetails?.token) {
                return res.json({
                    ...sessionDetails,
                    isExisting: true,
                });
            }
        }
        
        // Create new guest session
        const session = await chat.createGuestSession({
            ip,
            fingerprint,
            agentId: req.body.agentId,
            metadata: {
                userAgent: req.headers['user-agent'],
            },
        });

        res.json(session);
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

app.listen(3000);

Next.js API Route

// pages/api/session.js
import { OblienClient, OblienChat } from 'oblien';

const client = new OblienClient({
    apiKey: process.env.OBLIEN_API_KEY,
    apiSecret: process.env.OBLIEN_API_SECRET,
});

const chat = new OblienChat(client);

export default async function handler(req, res) {
    if (req.method !== 'POST') {
        return res.status(405).json({ error: 'Method not allowed' });
    }

    try {
        // For guests
        if (!req.headers.authorization) {
            const ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
            const fingerprint = req.body.fingerprint;
            
            const session = await chat.createGuestSession({
                ip,
                fingerprint, // Dual-layer identification
                agentId: req.body.agentId,
            });

            return res.json(session);
        }

        // For authenticated users
        const session = await chat.createSession({
            agentId: req.body.agentId,
            namespace: req.user.id, // User ID for tracking
        });

        res.json(session);
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
}

Environment Variables

OBLIEN_API_KEY=your-api-key
OBLIEN_API_SECRET=your-api-secret
OBLIEN_BASE_URL=https://api.oblien.com  # Optional

Storage Comparison

| Feature | NodeCache (Default) | InMemory | Redis | |---------|-------------------|----------|-------| | Setup | ✅ Zero config | ✅ Zero config | ⚠️ Requires Redis | | Auto-expiry | ✅ Yes | ✅ Manual | ✅ Yes | | Memory limit | ✅ Configurable | ❌ No | ✅ Configurable | | Statistics | ✅ Yes | ❌ No | ⚠️ Via Redis | | Distributed | ❌ Single instance | ❌ Single instance | ✅ Multi-server | | Persistence | ❌ Memory only | ❌ Memory only | ✅ Disk backup | | Production | ✅ Recommended | ❌ Dev only | ✅ High-traffic |

When to Use What:

  • NodeCache: Most applications, single server, < 100K guests/day ✅ Recommended
  • InMemory: Development, testing, quick prototypes
  • Redis: Distributed systems, > 1M guests/day, need persistence

Examples

Check the /examples folder for complete examples:

  • raw.js - Complete test suite demonstrating all features
  • express-server.js - Full Express.js implementation
  • nextjs-api-route.js - Next.js API routes (App Router & Pages Router)
  • with-redis.js - Production setup with Redis

Run the test example:

cd node_modules/oblien
node examples/raw.js

TypeScript Support

Full TypeScript definitions included:

import { OblienClient, OblienChat } from 'oblien';

const client: OblienClient = new OblienClient({
    apiKey: string,
    apiSecret?: string,
});

const chat: OblienChat = new OblienChat(client);

FAQ

Q: Do I need Redis?

A: No! NodeCache works great for most applications. Use Redis only if you need multi-server support or very high traffic.

Q: How does guest rate limiting work?

A: Guest sessions are automatically rate-limited by the Oblien API based on the namespace (guest ID). Limits:

  • 100K tokens/day
  • 50 messages/day
  • 20 messages/hour

Q: How does dual-layer identification work?

A: The package tracks guests using both IP address and browser fingerprint:

// First visit: Creates guest with IP + fingerprint
await chat.createGuestSession({
    ip: '1.2.3.4',
    fingerprint: 'abc123',
    agentId: 'agent-id',
});

// Same user, different IP (e.g., mobile network)
// → Same guest detected by fingerprint ✅
await chat.createGuestSession({
    ip: '5.6.7.8',        // Different IP
    fingerprint: 'abc123', // Same fingerprint
    agentId: 'agent-id',
});

// Same user, different fingerprint (e.g., cleared browser data)
// → Same guest detected by IP ✅
await chat.createGuestSession({
    ip: '1.2.3.4',        // Same IP
    fingerprint: 'xyz789', // Different fingerprint
    agentId: 'agent-id',
});

Q: Can I use custom guest IDs instead of IP?

A: Yes! Pass it as the namespace:

await chat.createSession({
    agentId: 'agent-id',
    isGuest: true,
    namespace: 'custom-guest-id',
});

Q: How do I clean up expired guests?

A: Call chat.cleanupGuests() periodically (e.g., cron job or setInterval).

Performance

Benchmarks on standard server:

  • Session creation: ~50ms
  • Guest lookup (cached): ~1ms
  • Guest cleanup (1000 guests): ~100ms

Dependencies

  • node-cache - Built-in caching (included)
  • redis - Optional, for distributed systems (peer dependency)

License

MIT

Links