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

indigenius-ai-widget

v1.1.4

Published

TypeScript-compatible AI Widget SDK for Cdial with npm and CDN support

Downloads

43

Readme

Indigenius AI Widget

CdialWidget is a powerful SDK for integrating AI Agent call widget into your web application, offering functionalities to easily initiate and manage calls with your AI-powered customer service agents.

✨ Features

  • 🎯 Full TypeScript Support - Complete type definitions included
  • 📦 Multiple Installation Methods - npm, CDN, or direct URL
  • ⚛️ Framework Agnostic - Works with React, Vue, Angular, Next.js, and more
  • 🌐 Browser Compatible - Works in all modern browsers
  • 🔧 Zero Configuration - Auto-detects TypeScript and provides IntelliSense
  • 🎨 Customizable UI - Use built-in UI or build your own

Installation

To use the SDK in your project, you can either:

1. Install via npm (Recommended - Full TypeScript Support)

npm install indigenius-ai-widget

TypeScript types are automatically included! No need for @types/ packages or manual declarations.

2. Include the UMD build via CDN (For HTML/JavaScript projects)

<script src="https://cdn.jsdelivr.net/npm/indigenius-ai-widget@latest/dist/sdk.umd.js"></script>

For TypeScript types with CDN usage, add this to your tsconfig.json:

{
  "compilerOptions": {
    "types": ["node_modules/indigenius-ai-widget/dist/index.d.ts"]
  }
}

Or install types separately:

npm install --save-dev indigenius-ai-widget

3. Include the official URL (Direct integration)

<script type="module" src="https://widget.indigenius.ai/v1/index.js"></script>

🚀 TypeScript Usage

The SDK is fully TypeScript compatible with complete type definitions included. No additional setup required!

Next.js Example (App Router)

// app/components/CdialWidget.tsx
'use client';

import { useEffect, useRef, useState } from 'react';
import { Cdial } from 'indigenius-ai-widget';

export default function CdialWidgetComponent() {
  const widgetRef = useRef<Cdial.CdialWidget | null>(null);
  const [callState, setCallState] = useState<'idle' | 'dialing' | 'connected' | 'ended'>('idle');
  const [isReady, setIsReady] = useState(false);

  useEffect(() => {
    // Dynamic import to avoid SSR issues
    import('indigenius-ai-widget').then(({ CdialWidget }) => {
      const widget = new CdialWidget({
        agentId: 'your-agent-id',
        mountUI: false, // Control from your own UI
      });

      widgetRef.current = widget;

      // Type-safe event listeners
      widget.on('dialing', () => setCallState('dialing'));
      widget.on('connected', () => setCallState('connected'));
      widget.on('ended', () => setCallState('ended'));
      widget.on('error', (error) => console.error('Widget error:', error));

      widget.init();
      setIsReady(true);
    });

    return () => widgetRef.current?.destroy();
  }, []);

  const toggleCall = () => {
    widgetRef.current?.toggleCall();
  };

  return (
    <div>
      <h1>AI Agent Widget</h1>
      <button 
        onClick={toggleCall} 
        disabled={!isReady}
        className="px-4 py-2 bg-blue-500 text-white rounded"
      >
        {callState === 'connected' ? '🔴 End Call' : 
         callState === 'dialing' ? '⏳ Dialing...' : 
         '📞 Start Call'}
      </button>
      {!isReady && <p>Loading widget...</p>}
    </div>
  );
}

TypeScript with Vite/React

// src/components/Widget.tsx
import { useEffect, useRef, useState } from 'react';
import { Cdial, CdialWidget, CdialWidgetOptions } from 'indigenius-ai-widget';

function Widget() {
  const widgetRef = useRef<Cdial.CdialWidget | null>(null);
  const [callState, setCallState] = useState<'idle' | 'dialing' | 'connected' | 'ended'>('idle');

  useEffect(() => {
    // Type-safe options
    const options: CdialWidgetOptions = {
      agentId: process.env.VITE_AGENT_ID || 'your-agent-id',
      mountUI: true,
    };

    const widget = new CdialWidget(options);
    widgetRef.current = widget;

    // Fully typed event handlers
    widget.on('dialing', () => setCallState('dialing'));
    widget.on('connected', () => setCallState('connected'));
    widget.on('ended', () => setCallState('ended'));
    widget.on('error', (err) => {
      console.error('Error:', err);
    });

    widget.init();

    return () => widget.destroy();
  }, []);

  return (
    <div>
      <h1>Status: {callState}</h1>
    </div>
  );
}

export default Widget;

Vue 3 + TypeScript

<!-- components/CdialWidget.vue -->
<template>
  <div>
    <h1>AI Agent Widget - {{ callState }}</h1>
    <button @click="toggleCall" :disabled="!isReady">
      {{ buttonLabel }}
    </button>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue';
import { Cdial, CdialWidget } from 'indigenius-ai-widget';

type CallState = 'idle' | 'dialing' | 'connected' | 'ended';

const callState = ref<CallState>('idle');
const isReady = ref(false);
let widget: Cdial.CdialWidget | null = null;

onMounted(() => {
  widget = new CdialWidget({
    agentId: 'your-agent-id',
    mountUI: false,
  });

  widget.on('dialing', () => (callState.value = 'dialing'));
  widget.on('connected', () => (callState.value = 'connected'));
  widget.on('ended', () => (callState.value = 'ended'));
  widget.on('error', (err) => console.error(err));

  widget.init();
  isReady.value = true;
});

onBeforeUnmount(() => {
  widget?.destroy();
});

const toggleCall = () => widget?.toggleCall();

const buttonLabel = computed(() =>
  callState.value === 'connected' ? 'End Call' : 'Start Call'
);
</script>

Angular with TypeScript

// app/components/widget/widget.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Cdial, CdialWidget, CdialWidgetOptions } from 'indigenius-ai-widget';

@Component({
  selector: 'app-cdial-widget',
  template: `
    <div>
      <h1>AI Agent Widget - {{ callState }}</h1>
      <button (click)="toggleCall()" [disabled]="!isReady">
        {{ buttonLabel }}
      </button>
    </div>
  `,
  styles: [`
    button {
      padding: 10px 20px;
      font-size: 16px;
      cursor: pointer;
    }
    button:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
  `]
})
export class WidgetComponent implements OnInit, OnDestroy {
  callState: 'idle' | 'dialing' | 'connected' | 'ended' = 'idle';
  isReady = false;
  private widget: Cdial.CdialWidget | null = null;

  get buttonLabel(): string {
    switch (this.callState) {
      case 'connected': return '🔴 End Call';
      case 'dialing': return '⏳ Dialing...';
      default: return '📞 Start Call';
    }
  }

  ngOnInit(): void {
    const options: CdialWidgetOptions = {
      agentId: 'your-agent-id',
      mountUI: false,
    };

    this.widget = new CdialWidget(options);

    this.widget.on('dialing', () => {
      this.callState = 'dialing';
    });

    this.widget.on('connected', () => {
      this.callState = 'connected';
    });

    this.widget.on('ended', () => {
      this.callState = 'ended';
    });

    this.widget.on('error', (err) => {
      console.error('Widget error:', err);
    });

    this.widget.init();
    this.isReady = true;
  }

  ngOnDestroy(): void {
    this.widget?.destroy();
  }

  toggleCall(): void {
    this.widget?.toggleCall();
  }
}

Vanilla TypeScript

// src/app.ts
import { Cdial, CdialWidget, CdialWidgetOptions } from 'indigenius-ai-widget';

class App {
  private widget: Cdial.CdialWidget;

  constructor() {
    const options: CdialWidgetOptions = {
      agentId: 'your-agent-id',
      mountUI: true,
    };

    this.widget = new CdialWidget(options);
    this.setupEventListeners();
    this.widget.init();
  }

  private setupEventListeners(): void {
    this.widget.on('dialing', () => {
      console.log('Call is dialing...');
      this.updateUI('dialing');
    });

    this.widget.on('connected', () => {
      console.log('Call connected!');
      this.updateUI('connected');
    });

    this.widget.on('ended', () => {
      console.log('Call ended');
      this.updateUI('ended');
    });

    this.widget.on('error', (error) => {
      console.error('Call error:', error);
      alert(`Error: ${error}`);
    });
  }

  private updateUI(state: string): void {
    const statusEl = document.getElementById('status');
    if (statusEl) {
      statusEl.textContent = `Status: ${state}`;
    }
  }

  public cleanup(): void {
    this.widget.destroy();
  }
}

// Initialize the app
const app = new App();

// Cleanup on page unload
window.addEventListener('beforeunload', () => {
  app.cleanup();
});

TypeScript Type Definitions

The package exports the following types:

// Namespace export
import { Cdial } from 'indigenius-ai-widget';

// Named exports
import { CdialWidget, CdialWidgetOptions } from 'indigenius-ai-widget';

// Types
type CallState = 'idle' | 'dialing' | 'connected' | 'ended';
type EventType = 'dialing' | 'connected' | 'ended' | 'error';
type EventCallback = (data?: any) => void;

// Options interface
interface CdialWidgetOptions {
  agentId: string;
  mountUI?: boolean; // default: false
}

// Widget class methods
class CdialWidget {
  constructor(options: CdialWidgetOptions);
  init(): void;
  startCall(theme?: any): Promise<void>;
  endCall(): void;
  toggleCall(): void;
  isCalling(): boolean;
  destroy(): void;
  on(event: EventType, callback: EventCallback): void;
}

🌐 CDN Usage with TypeScript

For projects using the CDN version but still want TypeScript support:

Option 1: Install Types Only

npm install --save-dev indigenius-ai-widget

Then in your HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Widget with CDN + TypeScript</title>
</head>
<body>
  <indigenius-convai agent-id="your-agent-id"></indigenius-convai>
  
  <!-- CDN Script -->
  <script src="https://cdn.jsdelivr.net/npm/indigenius-ai-widget@latest/dist/sdk.umd.js"></script>
  
  <script>
    // TypeScript will recognize Cdial and CdialWidget types
    window.addEventListener('load', () => {
      const widget = window.widget; // Fully typed!
      
      widget.on('connected', () => {
        console.log('Connected');
      });
    });
  </script>
</body>
</html>

Option 2: Type Reference from CDN

Types are available at these URLs:

  • jsDelivr: https://cdn.jsdelivr.net/npm/indigenius-ai-widget@latest/dist/index.d.ts
  • unpkg: https://unpkg.com/indigenius-ai-widget@latest/dist/index.d.ts

You can reference them in your TypeScript project or create a local type declaration.

Option 3: Manual Type Declaration

Create a indigenius-ai-widget.d.ts file in your project:

declare module 'indigenius-ai-widget' {
  export namespace Cdial {
    interface CdialWidgetOptions {
      agentId: string;
      mountUI?: boolean;
    }
    
    class CdialWidget {
      constructor(options: CdialWidgetOptions);
      init(): void;
      toggleCall(): void;
      startCall(theme?: any): Promise<void>;
      endCall(): void;
      isCalling(): boolean;
      destroy(): void;
      on(event: 'dialing' | 'connected' | 'ended' | 'error', callback: (data?: any) => void): void;
    }
  }
  
  export const CdialWidget: typeof Cdial.CdialWidget;
  export type CdialWidgetOptions = Cdial.CdialWidgetOptions;
}

declare global {
  interface Window {
    Cdial: typeof import('indigenius-ai-widget').Cdial;
    CdialWidget: typeof import('indigenius-ai-widget').CdialWidget;
    widget?: InstanceType<typeof import('indigenius-ai-widget').CdialWidget>;
  }
}

export {};

HTML Integration

You can integrate the widget into your HTML file with the following steps:

  1. Add the <indigenius-convai> component to your HTML body to display the widget.
  2. Include the SDK script (either from a CDN or local build).
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Webapp</title>
  </head>
  <body>
    <h1>Welcome to my random HTML site...</h1>

    <!-- Add the widget component -->
    <indigenius-convai agent-id="your-agent-id"></indigenius-convai>

    <!-- Add the SDK script (local or CDN) -->
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/[email protected]/dist/sdk.umd.js"
    ></script>

    <script defer>
      // Initialize event listeners
      window.addEventListener("load", () => {
        widget.on("dialing", () => {
          console.log("Dialing detected");
        });
        widget.on("connected", () => {
          console.log("Connected detected");
        });
        widget.on("ended", () => {
          console.log("Ended detected");
        });
        widget.on("error", (err) => {
          console.error("Error:", err);
        });
      });
    </script>
  </body>
</html>

Framework Usage

Widget Options (CdialWidget Constructor Payload)

When creating a new CdialWidget instance, you pass an options object. Here are the available options:

| Option | Type | Required | Default | Description | |------------|-----------|----------|---------|-----------------------------------------------------------------------------| | agentId | string | Yes | — | The unique Agent ID for your AI agent. | | mountUI | boolean | No | false | If true, the widget's floating UI is auto-mounted. If false, no UI is rendered and you control everything via the API. |

Example:

const widget = new CdialWidget({
  agentId: 'your-agent-id',
  mountUI: true, // Set to false to use your own UI
});

Initialize the Widget

The init method is used to initialize the widget with your options. You must provide a valid agentId. If you set mountUI: true, the widget's floating UI will appear automatically. If mountUI: false, you can build your own UI and control the widget programmatically.

import { CdialWidget } from "indigenius-ai-widget";

const widget = new CdialWidget({
  agentId: "your-agent-id",
  mountUI: true, // or false for custom UI
});

widget.init().then(() => {
  console.log("Widget initialized");
});

Toggle Call

Use toggleCall to start or end a call. This method toggles the widget between the "call in progress" state and the "idle" state.

widget.toggleCall(); // Starts or ends the call based on the current state

You can listen to events related to call state changes.

Event Listeners

The SDK supports various events that you can listen to for user interaction or state changes.

Example: Listening to Call Start and End Events

// Listen to call started
widget.on("callStarted", () => {
  console.log("Call has started");
});

// Listen to call ended
widget.on("callEnded", () => {
  console.log("Call has ended");
});

Destroy the Widget

To clean up and remove the widget from the page, use the destroy method. This is useful if you need to remove the widget entirely after use.

widget.destroy();

This method will remove all elements created by the widget and stop any ongoing call operations.


Full Example

Here’s a complete example of how to use the widget:


Modern Framework Integration

You can use the widget in React, Vue, or Angular. The mountUI option gives you full control over whether the floating widget UI appears, or if you want to build your own UI and use the widget's API.


React Example (Live Demo)

import './App.css';
import { useEffect, useRef, useState } from 'react';
import { CdialWidget } from 'indigenius-ai-widget';

function App() {
  const widgetRef = useRef(null);
  const [callState, setCallState] = useState('idle');
  const [widgetReady, setWidgetReady] = useState(false);

  useEffect(() => {
    // Use mountUI: false to control the call from your React button only
    const widget = new CdialWidget({
      agentId: 'your-agent-id',
      mountUI: false, // Only your React button will control the call
    });
    widgetRef.current = widget;

    widget.on('dialing', () => setCallState('dialing'));
    widget.on('connected', () => setCallState('connected'));
    widget.on('ended', () => setCallState('ended'));
    widget.on('error', console.error);

    widget.init().then(() => setWidgetReady(true));

    return () => widget.destroy();
  }, []);

  const toggleCall = () => widgetRef.current?.toggleCall();

  return (
    <div>
      <h1>Cdial Widget Demo</h1>
      <button onClick={toggleCall} disabled={!widgetReady}>
        {callState === 'connected'
          ? 'End Call'
          : callState === 'dialing'
          ? 'Dialing...'
          : 'Start Call'}
      </button>
      {!widgetReady && <p>Loading widget...</p>}
    </div>
  );
}

export default App;

Vue Example (Live Demo: N/A)

<template>
  <div>
    <h1>Cdial Widget Demo (Vue)</h1>
    <button @click="toggleCall">{{ buttonLabel }}</button>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, computed } from 'vue';
import { CdialWidget } from 'indigenius-ai-widget';

const callState = ref('idle');
let widget = null;

onMounted(() => {
  widget = new CdialWidget({
    agentId: 'your-agent-id',
    mountUI: true, // Set to false to use your own UI
  });

  widget.on('dialing', () => callState.value = 'dialing');
  widget.on('connected', () => callState.value = 'connected');
  widget.on('ended', () => callState.value = 'ended');
  widget.on('error', console.error);

  widget.init();
});

onBeforeUnmount(() => {
  widget?.destroy();
});

const toggleCall = () => widget?.toggleCall();

const buttonLabel = computed(() =>
  callState.value === 'connected' ? 'End Call' : 'Start Call'
);
</script>

Angular Example (Live Demo: N/A)

// app.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { CdialWidget } from 'indigenius-ai-widget';

@Component({
  selector: 'app-root',
  template: `
    <h1>Cdial Widget Demo (Angular)</h1>
    <button (click)="toggleCall()">{{ buttonLabel }}</button>
  `
})
export class AppComponent implements OnInit, OnDestroy {
  callState = 'idle';
  widget: any;

  get buttonLabel() {
    return this.callState === 'connected' ? 'End Call' : 'Start Call';
  }

  ngOnInit() {
    this.widget = new CdialWidget({
      agentId: 'your-agent-id',
      mountUI: true, // Set to false to use your own UI
    });

    this.widget.on('dialing', () => this.callState = 'dialing');
    this.widget.on('connected', () => this.callState = 'connected');
    this.widget.on('ended', () => this.callState = 'ended');
    this.widget.on('error', console.error);

    this.widget.init();
  }

  ngOnDestroy() {
    this.widget?.destroy();
  }

  toggleCall() {
    this.widget?.toggleCall();
  }
}

Summary

  • mountUI: true — Widget’s floating UI is auto-mounted (recommended for most use cases).
  • mountUI: false — No UI is rendered; you control everything via the widget API (advanced/custom UI).
  • The widget is fully self-contained and will not create duplicate UIs, even if instantiated multiple times in a framework.
  • All public methods (init, destroy, toggleCall, on, etc.) are available on the widget instance.

Methods

init()

Initializes the widget with the given agentId and sets up the UI.

Returns: Promise<void>

toggleCall()

Starts or ends a call based on the current widget state.

Returns: void

destroy()

Destroys the widget, removing all associated elements and cleaning up resources.

Returns: void


Events

The widget emits several events that you can listen to for customizing your application's behavior. Below is a list of available events, their descriptions, and usage examples.

📡 dialing

Emitted when the widget starts attempting to connect to the AI agent.

Example:

myCdialWidget.on("dialing", () => {
  console.log("Dialing detected");
});

🔗 connected

Emitted when the connection to the AI agent is successfully established.

Example:

myCdialWidget.on("connected", () => {
  console.log("Connected detected");
});

ended

Emitted when the call has ended or was terminated.

Example:

myCdialWidget.on("ended", () => {
  console.log("Ended detected");
});

⚠️ error

Emitted if there is an internal error during the operation of the widget.

Payload: err (Error or string) – details about the error that occurred.

Example:

myCdialWidget.on("error", (err) => {
  console.error("Error:", err);
});

You can register these event listeners after the widget has loaded:

<script defer>
  window.addEventListener("load", () => {
    myCdialWidget.on("dialing", () => {
      console.log("Dialing detected");
    });

    myCdialWidget.on("connected", () => {
      console.log("Connected detected");
    });

    myCdialWidget.on("ended", () => {
      console.log("Ended detected");
    });

    myCdialWidget.on("error", (err) => {
      console.error("Error:", err);
    });
  });
</script>

🔧 TypeScript Verification

Verify Types are Working

After installing the package, verify TypeScript support:

// test.ts
import { Cdial, CdialWidget } from 'indigenius-ai-widget';

// Should show IntelliSense for options
const widget = new CdialWidget({
  agentId: 'test', // ✅ Required
  mountUI: true,   // ✅ Optional with autocomplete
});

// Should show method autocomplete
widget.init();
widget.toggleCall();
widget.on('connected', () => {}); // ✅ Event names autocompleted
widget.destroy();

Run TypeScript compiler:

npx tsc test.ts --noEmit

If no errors appear, TypeScript is configured correctly! ✅

Troubleshooting TypeScript

Problem: Types not detected

Solutions:

  1. Ensure package is installed: npm install indigenius-ai-widget
  2. Restart your IDE/TypeScript server
  3. Check tsconfig.json has moduleResolution: "node"
  4. Run npm install again to refresh types

Problem: CDN usage without types

Solution:

# Install types as dev dependency
npm install --save-dev indigenius-ai-widget

IDE Support

The package works with:

  • ✅ VS Code (IntelliSense + autocomplete)
  • ✅ WebStorm/IntelliJ IDEA
  • ✅ Sublime Text (with LSP)
  • ✅ Vim/Neovim (with CoC or LSP)

📚 Additional Resources


This SDK is released under the MIT License. See LICENSE for more details.