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

@kaily-ai/chat-sdk

v2.1.3

Published

Kaily Chat SDK — build AI chat experiences with Kaily.ai copilots

Readme

@kaily-ai/chat-sdk

A TypeScript SDK for integrating Kaily.ai copilot chat into your applications. Real-time messaging, streaming responses, thread management, custom tools, and more.

Installation

npm install @kaily-ai/chat-sdk

Quick Start

import { CopilotPlatform } from '@kaily-ai/chat-sdk';

// 1. Initialize the SDK
const copilot = CopilotPlatform.getInstance({
  environment: 'production',
  surfaceClient: 'web',
});

// 2. Create a bot instance with your copilot app token
const bot = await copilot.createBotInstance('YOUR_APP_TOKEN');

// 3. Send a message
await bot.message(
  { text: 'Hello!' },
  {
    deltaListener: (res) => console.log('Streaming:', res.data.content),
    replyListener: (res) => console.log('Reply:', res.data),
    progressListener: (res) => console.log('Progress:', res.data.progress),
    toolMessageListener: (res) => console.log('Tool:', res.data),
  }
);

SDK Initialization

import { CopilotPlatform } from '@kaily-ai/chat-sdk';

// Single instance (default)
const copilot = CopilotPlatform.getInstance({
  environment: 'production',       // 'production' | 'uat' | 'sit'
  surfaceClient: 'web',            // Your client identifier
});

// Named instance (for multi-instance)
const copilot = CopilotPlatform.createInstance('my-widget', {
  environment: 'production',
  surfaceClient: 'web',
});

| Property | Type | Required | Description | |----------|------|----------|-------------| | environment | 'production' \| 'uat' \| 'sit' | Recommended | Target environment | | surfaceClient | string | Yes | Your client identifier |

Multi-Instance Support

Run multiple independent widgets on the same page — each with its own socket, events, and state:

const sales = CopilotPlatform.createInstance('sales', { environment: 'production', surfaceClient: 'web' });
const support = CopilotPlatform.createInstance('support', { environment: 'production', surfaceClient: 'web' });

const salesBot = await sales.createBotInstance('SALES_TOKEN');
const supportBot = await support.createBotInstance('SUPPORT_TOKEN');

// Retrieve later
const widget = CopilotPlatform.getInstanceById('sales');

// Cleanup
sales.destroy(); // other instances unaffected

getInstance() still works exactly as before for single-widget use cases.

Messaging

const result = await bot.message(
  {
    text: 'What is the status of my order?',
    thread_id: 'optional-thread-id',
  },
  {
    deltaListener: (res) => {
      // Real-time streaming chunks
      console.log(res.data.content);
    },
    replyListener: (res) => {
      // Final complete response
      console.log(res.data.messages);
    },
    progressListener: (res) => {
      // Progress updates (e.g., "Searching...")
      console.log(`${res.data.progress}%`, res.data.content);
    },
    toolMessageListener: (res) => {
      // Tool execution output
      console.log(res.data.content);
    },
    toolComponentMessageListener: (res) => {
      // Custom component responses from tools
      console.log(res.data.content);
    },
  }
);

Stop Generation

await bot.stopMessage({ thread_id: 'thread-id' });

Thread Management

const threads = await bot.getThreads({ page: 1, limit: 20 });
const messages = await bot.getMessages({ threadId: 'thread-id' });
await bot.updateThread({ threadId: 'thread-id', title: 'New Title' });
await bot.deleteThread('thread-id');
await bot.deleteAllThreads({});

Custom Tools

Register client-side tools that the AI can invoke during conversations:

import { Tool } from '@kaily-ai/chat-sdk';

await bot.addTool({
  name: 'lookupOrder',
  description: 'Look up order status by order ID',
  timeout: 5000,
  parameters: {
    type: 'object',
    properties: {
      orderId: { type: 'string', description: 'The order ID' },
    },
    required: ['orderId'],
  },
  handler: async (params) => {
    const order = await fetchOrder(params.orderId);
    return { status: order.status, eta: order.eta };
  },
});

// Remove tools
await bot.removeTool('lookupOrder');
await bot.removeAllTools();

User Management

await bot.setUser({
  name: 'John Doe',
  email: '[email protected]',
  phone: '+1234567890',
  additionalFields: { company: 'Acme Inc' },
});

await bot.unsetUser();

Context

await bot.setContext({
  currentPage: '/products',
  cartItems: 3,
});

Component Actions

await bot.componentAction('thread-id', 'message-id', {
  rating: 'positive',
});

updateMessage and EVENTS.COMPONENT_SELECTION_SAVE (copilot:component:selection:save) are deprecated compatibility APIs. Use componentAction and EVENTS.COMPONENT_ACTION (copilot:component:action:handler) instead.

API Reference

CopilotPlatform

| Method | Description | |--------|-------------| | getInstance(options) | Get or create default instance | | createInstance(id, options) | Create a named, isolated instance | | getInstanceById(id) | Retrieve existing instance by ID | | destroy() | Destroy instance (sockets, events, registry) | | createBotInstance(token) | Create bot instance | | getBot() | Get current bot | | switchBot(token) | Switch to different bot |

CopilotBot

| Method | Description | |--------|-------------| | message(message, listeners) | Send message with streaming | | stopMessage(options) | Stop generation | | getThreads(request) | Get all threads | | getMessages(request) | Get thread messages | | updateThread(request) | Update thread | | deleteThread(threadId) | Delete thread | | componentAction(threadId, messageId, data) | Persist component action data | | updateMessage(threadId, messageId, data) | Deprecated. Use componentAction instead | | addTool(tools) | Add custom tools | | removeTool(name) | Remove tool | | setContext(context) | Set conversation context | | setUser(request) | Set user details | | unsetUser() | Clear user | | feedback(request) | Submit feedback | | captureData(request) | Capture analytics | | destroy() | Cleanup |

Type Definitions

type Environment = 'production' | 'uat' | 'sit';

interface MessageModel {
  text: string;
  path: string;
  thread_id?: string;
  files?: Array<any>;
  info?: { custom_data?: any };
}

interface Tool {
  name: string;
  description?: string;
  parameters?: object;
  timeout: number;
  handler: (params: Record<string, any>) => any | Promise<any>;
}

License

MIT