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

@illuma-ai/agentviz

v1.0.1

Published

Embeddable agent chat widget — stream LLM responses with DOM extraction, theming, and markdown rendering

Readme

@illuma-ai/agentviz

Embeddable, framework-agnostic agent chat widget. Stream LLM responses with markdown rendering, file attachments, text selection summaries, and complete style isolation via Shadow DOM.

  • Two widget types: Inline Summary (icon → summary/analysis) and Agent Chat (full conversation)
  • Multiple display modes: Popover, drawer, FAB (floating action button), DOM injection
  • Text selection summary: Highlight any text → floating "Summarize" / "Ask" toolbar
  • Zero framework dependencies — works with React, Vue, Angular, or plain HTML
  • Full style isolation — Shadow DOM + all: initial CSS reset, no parent style leakage
  • Dark & light themes with full color token customization

Installation

npm install @illuma-ai/agentviz

Or via CDN (IIFE bundle — exposes AgentViz and SelectionSummary globals):

<script src="https://unpkg.com/@illuma-ai/agentviz/dist/agentviz.iife.js"></script>

Quick Start

Agent Chat — FAB (Floating Action Button)

A circular chat icon pinned to the bottom-right of the viewport. Clicking opens a drawer.

import { AgentViz } from '@illuma-ai/agentviz';

const widget = new AgentViz({
  type: 'agent-chat',
  displayMode: 'fab',
  agentId: 'agent_xxx',
  url: 'https://app.illuma.ai',
  token: 'rat_xxx',
  icon: '<svg>...</svg>',  // or image URL
  brandName: 'Illuma',
  theme: 'dark',
});
widget.mount();

Inline Summary — Icon in Header

Place a summary icon next to any section. Clicking extracts the content and sends it to the agent.

import { AgentViz } from '@illuma-ai/agentviz';

const widget = new AgentViz({
  type: 'inline',
  agentId: 'agent_xxx',
  url: 'https://app.illuma.ai',
  token: 'rat_xxx',
  icon: '<svg>...</svg>',
  contentMode: 'dom',
  data: document.querySelector('#my-section'),
  displayMode: 'popover',
  parentElement: document.querySelector('#icon-container'),
  brandName: 'Illuma',
});
widget.mount();

Widget Types

type: "inline" — Inline Summary

An icon placed in the page DOM (header, toolbar, sidebar). When clicked, it extracts content based on contentMode and sends it to the agent for summary/analysis.

| Property | Type | Required | Description | |----------|------|----------|-------------| | type | "inline" | Yes | Widget type discriminator | | agentId | string | Yes | Agent ID for API calls | | url | string | Yes | API base URL | | token | string | Yes | API token (rat_...) | | icon | string | Yes | Icon SVG markup or image URL | | contentMode | "dom" \| "text" \| "json" | Yes | How content is delivered to the agent | | data | HTMLElement \| string \| object | Yes | Content payload (type depends on contentMode) | | displayMode | "popover" \| "drawer" | Yes | How the summary UI is displayed | | parentElement | HTMLElement | Yes | DOM element to mount the icon into | | chatEnabled | boolean | No | Show chat input for follow-up questions (default: false) | | attachAsContext | boolean | No | JSON mode only — how JSON data is sent (default: true) | | theme | "dark" \| "light" \| ThemeColors | No | Theme preset or custom colors (default: "dark") | | brandName | string | No | Brand name in header (default: "Agent") | | updateMemory | boolean | No | Pass updateMemory flag to API (default: false) |

Content Modes

// DOM — extract text/HTML from DOM elements
{ contentMode: 'dom', data: document.querySelector('#article') }
{ contentMode: 'dom', data: [el1, el2, el3] }  // multiple elements

// Text — send plain text directly
{ contentMode: 'text', data: 'Your text content to summarize...' }

// JSON — send structured data
{ contentMode: 'json', data: { revenue: 12500000, growth: 0.18 } }

Display Modes

// Popover — floating panel anchored to the icon
{ displayMode: 'popover' }

// Drawer — slide-in panel from the right
{ displayMode: 'drawer' }

type: "agent-chat" — Agent Chat

Full conversational chat with the agent. Three display modes with different UX patterns.

FAB (Floating Action Button)

Circular button pinned to bottom-right of viewport. Always opens a drawer.

new AgentViz({
  type: 'agent-chat',
  displayMode: 'fab',
  agentId: 'agent_xxx',
  url: 'https://app.illuma.ai',
  token: 'rat_xxx',
  icon: '<svg>...</svg>',
  fileAttach: true,   // enable file uploads
  theme: 'dark',
}).mount();

| Property | Type | Required | Description | |----------|------|----------|-------------| | displayMode | "fab" | Yes | FAB mode | | icon | string | Yes | Icon SVG or image URL for the FAB button | | fileAttach | boolean | No | Enable file attachment (default: false) |

Icon Inline

Icon embedded in your page DOM (header, toolbar, etc). Opens chat via popover or drawer.

new AgentViz({
  type: 'agent-chat',
  displayMode: 'icon-inline',
  parentElement: document.querySelector('#header-actions'),
  subDisplayMode: 'popover',  // or 'drawer'
  agentId: 'agent_xxx',
  url: 'https://app.illuma.ai',
  token: 'rat_xxx',
  icon: '<svg>...</svg>',
}).mount();

| Property | Type | Required | Description | |----------|------|----------|-------------| | displayMode | "icon-inline" | Yes | Icon inline mode | | parentElement | HTMLElement | Yes | DOM element to mount the icon into | | subDisplayMode | "popover" \| "drawer" | Yes | How the chat panel opens | | icon | string | Yes | Icon SVG or image URL |

DOM Inject

Chat injected directly into a container element. No icon, no overlay — the chat is part of your page layout.

new AgentViz({
  type: 'agent-chat',
  displayMode: 'dom-inject',
  parentElement: document.querySelector('#chat-container'),
  agentId: 'agent_xxx',
  url: 'https://app.illuma.ai',
  token: 'rat_xxx',
}).mount();

| Property | Type | Required | Description | |----------|------|----------|-------------| | displayMode | "dom-inject" | Yes | DOM inject mode | | parentElement | HTMLElement | Yes | Container to inject chat into | | icon | string | No | Not typically needed |


Selection Summary

Global text-selection feature. Users highlight text anywhere on the page and get a floating toolbar with "Summarize" and "Ask" actions.

import { SelectionSummary } from '@illuma-ai/agentviz';

// Enable once at app level — works across all pages
SelectionSummary.enable({
  agentId: 'agent_xxx',
  url: 'https://app.illuma.ai',
  token: 'rat_xxx',
  brandName: 'Illuma',
  theme: 'dark',
  chatEnabled: true,  // allow follow-up questions after summary
});

// Disable when no longer needed
SelectionSummary.disable();

| Property | Type | Required | Description | |----------|------|----------|-------------| | agentId | string | Yes | Agent ID | | url | string | Yes | API base URL | | token | string | Yes | API token | | brandName | string | No | Shown in toolbar and popover header | | theme | "dark" \| "light" \| ThemeColors | No | Theme (default: "dark") | | chatEnabled | boolean | No | Show chat input for follow-up (default: false) | | icon | string | No | Custom icon for the toolbar button | | minSelectionLength | number | No | Minimum chars to trigger toolbar (default: 10) |


API Reference

AgentViz

class AgentViz {
  constructor(config: AgentVizConfig);

  /** Mount the widget into the DOM */
  mount(): void;

  /** Remove from DOM but preserve conversation state */
  unmount(): void;

  /** Full cleanup — remove from DOM, abort streams, reset state */
  destroy(): void;

  /** Send a message to the agent programmatically */
  sendMessage(text: string, files?: File[]): Promise<void>;

  /** Send content for inline widgets (extracts based on contentMode) */
  sendContent(): Promise<void>;

  /** Update theme at runtime */
  setTheme(theme: 'dark' | 'light' | Partial<ThemeColors>): void;

  /** Open the widget panel */
  open(): void;

  /** Close the widget panel (preserves conversation) */
  close(): void;
}

SelectionSummary

class SelectionSummary {
  /** Enable text-selection summary globally (singleton) */
  static enable(config: SelectionSummaryConfig): SelectionSummary;

  /** Disable and clean up */
  static disable(): void;

  /** Check if currently enabled */
  static isEnabled(): boolean;
}

Callbacks

new AgentViz({
  // ...
  onMessage: (msg) => console.log(`${msg.role}: ${msg.content}`),
  onError: (err) => console.error('Widget error:', err),
  onReady: () => console.log('Widget mounted'),
});

Theming

Built-in Themes

// Dark theme (default)
{ theme: 'dark' }

// Light theme
{ theme: 'light' }

Custom Colors

Override any color token from the base theme:

new AgentViz({
  // ...
  theme: {
    background: '#0f0f23',
    accent: '#8b5cf6',
    userBubble: '#7c3aed',
    userBubbleText: '#ffffff',
  },
});

Runtime Theme Switching

widget.setTheme('light');
widget.setTheme({ accent: '#e94560', background: '#1a1a2e' });

Color Tokens

| Token | Description | |-------|-------------| | background | Main widget background | | surface | Message bubble / card background | | surfaceHover | Hover state for interactive surfaces | | text | Primary text color | | textSecondary | Secondary / muted text | | primary | Primary brand color | | accent | Accent color for links, highlights | | border | Border color | | inputBackground | Chat input background | | inputText | Chat input text color | | inputBorder | Chat input border | | userBubble | User message bubble background | | userBubbleText | User message text color | | agentBubble | Agent message bubble background | | agentBubbleText | Agent message text color | | skeleton | Loading skeleton base color | | skeletonShimmer | Loading skeleton shimmer highlight | | error | Error text color | | scrollbarThumb | Scrollbar thumb color | | codeBackground | Code block background |


Framework Integration

React

import { useRef, useEffect } from 'react';
import { AgentViz } from '@illuma-ai/agentviz';

function ChatWidget() {
  const containerRef = useRef<HTMLDivElement>(null);
  const widgetRef = useRef<AgentViz | null>(null);

  useEffect(() => {
    if (!containerRef.current) return;

    const widget = new AgentViz({
      type: 'agent-chat',
      displayMode: 'dom-inject',
      parentElement: containerRef.current,
      agentId: 'agent_xxx',
      url: 'https://app.illuma.ai',
      token: 'rat_xxx',
      theme: 'dark',
    });
    widget.mount();
    widgetRef.current = widget;

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

  return <div ref={containerRef} style={{ height: 500 }} />;
}

React — Inline Summary Icon

function SectionWithSummary({ children }) {
  const iconRef = useRef<HTMLDivElement>(null);
  const contentRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!iconRef.current || !contentRef.current) return;

    const widget = new AgentViz({
      type: 'inline',
      agentId: 'agent_xxx',
      url: 'https://app.illuma.ai',
      token: 'rat_xxx',
      icon: '<svg>...</svg>',
      contentMode: 'dom',
      data: contentRef.current,
      displayMode: 'popover',
      parentElement: iconRef.current,
    });
    widget.mount();
    return () => widget.destroy();
  }, []);

  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <h2>Section Title</h2>
        <div ref={iconRef} />
      </div>
      <div ref={contentRef}>{children}</div>
    </div>
  );
}

Vue

<template>
  <div ref="container" style="height: 500px" />
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { AgentViz } from '@illuma-ai/agentviz';

const container = ref(null);
let widget = null;

onMounted(() => {
  widget = new AgentViz({
    type: 'agent-chat',
    displayMode: 'dom-inject',
    parentElement: container.value,
    agentId: 'agent_xxx',
    url: 'https://app.illuma.ai',
    token: 'rat_xxx',
  });
  widget.mount();
});

onUnmounted(() => widget?.destroy());
</script>

Plain HTML (IIFE)

<script src="https://unpkg.com/@illuma-ai/agentviz/dist/agentviz.iife.js"></script>

<script>
  // FAB — no container needed, auto-injects bottom-right
  new AgentViz({
    type: 'agent-chat',
    displayMode: 'fab',
    agentId: 'agent_xxx',
    url: 'https://app.illuma.ai',
    token: 'rat_xxx',
    icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',
  }).mount();

  // Selection Summary — global text highlight feature
  SelectionSummary.enable({
    agentId: 'agent_xxx',
    url: 'https://app.illuma.ai',
    token: 'rat_xxx',
    brandName: 'Illuma',
  });
</script>

Exports

// Main class (facade)
export { AgentViz } from './widget';

// Widget implementations (advanced use)
export { InlineWidget } from './widget-inline';
export { AgentChatWidget } from './widget-agent-chat';

// Selection Summary
export { SelectionSummary } from './selection-summary';
export type { SelectionSummaryConfig } from './selection-summary';

// Types
export type {
  AgentVizConfig,
  InlineWidgetConfig,
  AgentChatWidgetConfig,
  AgentChatFabConfig,
  AgentChatIconInlineConfig,
  AgentChatDomInjectConfig,
  AgentVizInstance,
  WidgetType,
  ContentMode,
  InlineDisplayMode,
  AgentChatDisplayMode,
  SubDisplayMode,
  ThemeColors,
  ThemeInput,
  Message,
  FileAttachment,
  StreamEvent,
} from './types';

// Theme presets
export { DARK_THEME, LIGHT_THEME } from './themes';

// Constants
export { ICONS, DEFAULTS, Z_INDEX } from './constants';

License

MIT — see LICENSE