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

@takesales/sdk

v0.1.33

Published

SDK for integrating Take Sales AI agents into custom UIs

Readme

Take Sales SDK

SDK for integrating Take Sales AI agents into custom UIs. Connect to the agent via WebSocket and build your own chat interface.

Using React? See the React integration guide.

Installation

npm install @takesales/sdk

Quick Start

import { TakeSalesClient } from '@takesales/sdk'

const client = new TakeSalesClient({
  agentId: 'your-agent-uuid',
  wsUrl: 'wss://api-agent.takesales.ai/ws',
})

client.on('connected', () => {
  console.log('Agent ready')
  client.sendText('Hello!')
})

client.on('agentConfig', (config) => {
  console.log('Agent:', config.agentName)
})

client.on('message', (text, endOfTurn) => {
  console.log('Agent says:', text)
  if (endOfTurn) console.log('--- turn complete ---')
})

client.on('richContent', (content) => {
  console.log('Rich content:', content.type, content.data)
})

client.on('error', (err) => {
  console.error('Error:', err)
})

client.on('disconnect', (code, reason) => {
  console.log('Disconnected:', code, reason)
})

client.connect()

API Reference

TakeSalesClient

Framework-agnostic WebSocket client.

Constructor

new TakeSalesClient(config: TakeSalesClientConfig)

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | agentId | string | Yes | Agent UUID | | wsUrl | string | Yes | WebSocket server URL | | visitor | object | No | Visitor info (see below) | | conversationId | string | No | Resume a previous session | | isTest | boolean | No | Mark as test session | | clientVariables | Record<string, string> | No | Pre-resolved client variables for tool enrichment | | clientVariableConfigs | ClientVariableConfig[] | No | Auto-resolve variables from browser (localStorage, cookies, etc.) | | reconnect | object | No | Reconnection settings |

visitor object:

| Field | Type | Description | |-------|------|-------------| | email | string | Visitor email | | name | string | Visitor name | | phone | string | Visitor phone | | contactData | Record<string, string> | Custom contact fields |

reconnect object:

| Field | Type | Default | Description | |-------|------|---------|-------------| | enabled | boolean | true | Enable auto-reconnect | | maxAttempts | number | 5 | Max reconnect attempts | | baseDelay | number | 1000 | Base delay in ms (exponential backoff) |

Methods

| Method | Description | |--------|-------------| | connect() | Open WebSocket connection | | disconnect() | Close connection (no auto-reconnect) | | sendText(text) | Send a text message | | sendFormSubmit(formId, data) | Submit a lead form | | sendScheduleConfirm(scheduleId, date, time) | Confirm a schedule | | sendToolConfirmation(confirmationId, confirmed) | Approve/reject a tool action | | sendUpdateVisitor(data) | Update visitor contact info |

Properties

| Property | Type | Description | |----------|------|-------------| | isConnected | boolean | Current connection state | | conversationId | string \| null | Current session ID | | agentConfig | ServerAgentConfig \| null | Agent configuration from server |

Events

client.on('connected', () => void)
client.on('message', (text: string, endOfTurn: boolean) => void)
client.on('richContent', (content: RichContent) => void)
client.on('agentConfig', (config: ServerAgentConfig) => void)
client.on('sessionCreated', (data: { conversationId: string }) => void)
client.on('toolConfirmation', (data: ToolConfirmation) => void)
client.on('usageWarning', (data: { message: string, warningType: string }) => void)
client.on('error', (error: string) => void)
client.on('disconnect', (code?: number, reason?: string) => void)

Use client.off(event, listener) to remove a listener.


Client Variables

Client variables allow authenticated tools to access data from the visitor's browser (localStorage, cookies, etc.). The SDK supports three modes:

Automatic (recommended)

When no clientVariables or clientVariableConfigs are provided, the SDK automatically fetches the agent's configuration via preflight and resolves variables from the browser — the same behavior as the embedded widget.

const client = new TakeSalesClient({
  agentId: 'your-agent-uuid',
  wsUrl: 'wss://api-agent.takesales.ai/ws',
  // Client variables are resolved automatically from preflight config
})

Manual

Pass pre-resolved values directly:

const client = new TakeSalesClient({
  agentId: 'your-agent-uuid',
  wsUrl: 'wss://api-agent.takesales.ai/ws',
  clientVariables: {
    auth_token: localStorage.getItem('token') ?? '',
    user_id: '12345',
  },
})

Config-based

Pass extraction configs (same format as the dashboard):

import { type ClientVariableConfig } from '@takesales/sdk'

const client = new TakeSalesClient({
  agentId: 'your-agent-uuid',
  wsUrl: 'wss://api-agent.takesales.ai/ws',
  clientVariableConfigs: [
    { name: 'auth_token', source: 'localStorage', key: 'token' },
    { name: 'user_id', source: 'cookie', key: 'uid' },
  ],
})

Supported sources: localStorage, sessionStorage, cookie, window, querySelector, meta.

If both clientVariables and clientVariableConfigs are provided, manual values take precedence.


Rich Content Types

The agent can send rich content alongside text messages. Each type has a specific data shape:

Carousel

{ type: 'carousel', data: CarouselCard[] }

interface CarouselCard {
  title: string
  description?: string
  imageUrl?: string
  url: string
  price?: string
  address?: string
  area?: string
  bedrooms?: number
  images?: string[]
}

Quick Replies

{ type: 'quick_replies', data: QuickReplyOption[] }

interface QuickReplyOption {
  label: string
  value: string
}

Usage: render buttons and call sendText(option.value) on click.

Lead Form

{ type: 'lead_form', data: LeadFormCard }

interface LeadFormCard {
  formId: string
  fields: Array<{
    key: string
    type: 'text' | 'email' | 'phone' | 'textarea'
    label: string
    placeholder?: string
    required: boolean
  }>
  submitLabel?: string
  successMessage?: string
}

Usage: render a form and call sendFormSubmit(formId, data) on submit.

Schedule Form

{ type: 'schedule_form', data: ScheduleFormCard }

interface ScheduleFormCard {
  availableSlots: Array<{ date: string; times: string[] }>
  propertyTitle?: string
  scheduleId?: string
}

Usage: render date/time picker and call sendScheduleConfirm(scheduleId, date, time).

Inline Map

{ type: 'inline_map', data: InlineMapCard }

interface InlineMapCard {
  lat: number
  lng: number
  address: string
  zoom?: number
  googleMapsApiKey?: string
}

Photo Gallery

{ type: 'photo_gallery', data: PhotoGalleryCard }

interface PhotoGalleryCard {
  images: string[]
  title?: string
}

Comparator

{ type: 'comparator', data: ComparatorCard }

interface ComparatorCard {
  properties: Array<{
    title: string
    url?: string
    imageUrl?: string
    price?: string
    area?: string
    bedrooms?: number
    bathrooms?: number
    differentials?: string[]
  }>
}

Tool Confirmation

When a tool has risk level confirm, the agent pauses execution and sends a confirmation event before proceeding. In the embedded widget, a confirmation card appears automatically in the chat. If you're using the SDK, you need to listen for the event and build your own UI.

{ type: 'tool_confirmation', data: ToolConfirmation }

interface ToolConfirmation {
  confirmationId: string
  toolName: string
  message: string
  details?: Record<string, unknown>
}

Example:

// 1. Listen for the confirmation event
client.on('toolConfirmation', (data) => {
  // data.toolName → tool name (e.g. "cancel_subscription")
  // data.message  → action description
  // data.details  → parameters to be sent (e.g. { userId: "123" })

  // Show a confirmation dialog/card in your UI
  showConfirmDialog({
    title: data.toolName,
    message: data.message,
    params: data.details,
    onConfirm: () => client.sendToolConfirmation(data.confirmationId, true),
    onCancel: () => client.sendToolConfirmation(data.confirmationId, false),
  });
});

If the visitor confirms, the tool executes normally. If they cancel, the agent receives a notice and continues the conversation without executing the action.


Agent Config

After connecting, you receive the agent configuration from the server:

interface ServerAgentConfig {
  agentId: string
  workspaceId: string
  agentName: string
  greeting: string
  avatarUrl: string | null
  language: string
  enableVoice: boolean
  enableTextChat: boolean
  collectVisitorEmail: boolean
  collectVisitorName: boolean
  collectVisitorPhone: boolean
  quickReplies?: string[]
  primaryColor?: string
  secondaryColor?: string
  textColor?: string
  backgroundColor?: string
  title?: string
  subtitle?: string
  // ... and more
}

Use this to style your UI, show the greeting, and configure contact collection.


Connection Lifecycle

connect()
  |
  v
Preflight fetch (auto-discovers client variable configs)
  |
  v
WebSocket open
  |
  v
Service setup sent (agent_id + visitor info + client variables)
  |
  v
Server sends: agentConfig  -->  'agentConfig' event
Server sends: sessionCreated  -->  'sessionCreated' event
  |
  v
Session setup sent (text-only mode)
  |
  v
Server sends: setupComplete  -->  'connected' event
  |
  v
Ready to send/receive messages
  |
  v
disconnect() or connection lost
  |
  v
Auto-reconnect (exponential backoff, up to 5 attempts)

Security

Authentication uses the same model as Google Maps or Stripe.js:

  • agentId is a public identifier (UUID) embedded in client code
  • Origin validation is enforced server-side via the agent's allowed origins list
  • Configure allowed origins in the Take Sales dashboard under Agent Settings

No API keys or bearer tokens are needed for client-side usage.


Examples

Resuming a session

const savedId = localStorage.getItem('conversationId')

const client = new TakeSalesClient({
  agentId: 'your-agent-uuid',
  wsUrl: 'wss://api-agent.takesales.ai/ws',
  conversationId: savedId ?? undefined,
})

client.on('sessionCreated', ({ conversationId }) => {
  localStorage.setItem('conversationId', conversationId)
})

client.connect()

With visitor identification

const client = new TakeSalesClient({
  agentId: 'your-agent-uuid',
  wsUrl: 'wss://api-agent.takesales.ai/ws',
  visitor: {
    email: '[email protected]',
    name: 'John Doe',
    phone: '+5511999999999',
  },
})

client.connect()