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

@wavespec/adapter-openai-chatkit

v0.1.0

Published

OpenAI ChatKit adapter for WaveSpec

Readme

@wavespec/adapter-openai-chatkit

OpenAI ChatKit Web Component adapter for WaveSpec testing framework.

Overview

This adapter integrates OpenAI's @openai/chatkit-react Web Component into WaveSpec's testing framework. Unlike other OpenAI adapters that wrap API clients, ChatKit is a UI component that requires DOM instantiation and communicates via CustomEvents.

Architecture

Core Components

  • WebComponentLifecycleManager: Manages <openai-chatkit> element lifecycle
  • EventBridge: Translates DOM CustomEvents to WaveSpec events
  • ConfigurationTranslator: Converts between WaveSpec SDKConfig and ChatKitOptions
  • WidgetNormalizer: Extracts and validates widget data
  • BackendProtocolHelpers: Testing utilities for backend integration
  • MockBackend: Mock server for testing ChatKit backend protocol

Key Features

  • ✅ Web Component testing in Node.js (jsdom)
  • ✅ Event-driven streaming support (real-time event observation)
  • ✅ DOM CustomEvent collection and translation
  • ✅ Widget system support (25+ component types)
  • ✅ Backend protocol mocking
  • ✅ File upload testing (two-phase and direct strategies)
  • ✅ React integration utilities

Installation

pnpm add @wavespec/adapter-openai-chatkit

Security Model

ChatKit uses a secure proxy pattern. Your OpenAI API key should NEVER be exposed to clients.

Critical Requirements

  1. Configure Domain Allowlist - Restrict which domains can use your ChatKit integration in the OpenAI Platform
  2. Implement User Authentication - Verify user identity before creating session tokens in your backend
  3. Protect API Keys - Store API keys in server-side environment variables only
  4. Review Security Guide - Read docs/security.md before deploying to production

Quick Security Check

  • Is your API key in client-side code? INSECURE
  • Is your domain allowlist set to *? INSECURE
  • Does your backend verify users before creating sessions? SECURE

Secure Architecture

Browser          Your Backend         OpenAI API
  |                    |                    |
  |  Domain Key +      |  API Key +         |
  |  Session Token     |  Session Token     |
  |                    |                    |
  +--------HTTPS-------> (Auth Check)       |
                       +-------HTTPS-------->

See Security Guide for complete documentation and Secure Examples for working code.

Table of Contents

Quick Start

WaveSpec Testing

import { OpenAIChatKitAdapter } from '@wavespec/adapter-openai-chatkit';

// Configure adapter
const config = {
  type: 'openai-chatkit',
  api: {
    // Custom backend configuration (url + domainKey)
    url: 'http://localhost:3000/chatkit',
    domainKey: 'dk_test_123'
  },
  theme: 'light',
  composer: { placeholder: 'Ask me anything...' }
};

// Create adapter instance
const adapter = new OpenAIChatKitAdapter();

// Connect
await adapter.connect(config, context);

// Run operations
const result = await adapter.run({
  operation: 'send_message',
  params: { text: 'Hello!' }
}, context);

// Disconnect
await adapter.disconnect();

Event-Driven Streaming

Stream events in real-time during operation execution:

// Use streamEvents() for real-time event observation
const generator = adapter.streamEvents({
  operation: 'send_message',
  params: { text: 'Hello!' }
}, context);

// Yield events as they occur
for await (const event of generator) {
  console.log('Event:', event.type, event.timestamp);
  
  if (event.type === 'response_start') {
    console.log('Response started');
  }
}

// Get final result after streaming completes
const finalIteration = await generator.next();
if (finalIteration.done) {
  const result = finalIteration.value;
  console.log('Result:', result);
}

See Streaming Guide for complete documentation.

Frontend Integration

React Example

import React from 'react';
import { ChatKit, useChatKit } from '@openai/chatkit-react';
import type { ChatKitOptions } from '@openai/chatkit';

export function MyChat() {
  const { control } = useChatKit({
    api: {
      url: 'http://localhost:3000/chatkit',
      domainKey: 'dk_your_domain_key'
    },
    onError: (event) => console.error('ChatKit error:', event.error),
    onThreadChange: (event) => console.log('Thread changed:', event.threadId),
    onResponseEnd: () => console.log('Response complete')
  } satisfies ChatKitOptions);

  return (
    <div>
      <button onClick={() => control.sendUserMessage({ text: 'Hello!' })}>
        Send Message
      </button>
      <button onClick={() => control.setThreadId(null)}>
        New Thread
      </button>
      <ChatKit control={control} className="h-[600px]" />
    </div>
  );
}

Vanilla JavaScript Example

<openai-chatkit id="chatkit"></openai-chatkit>

<script type="module">
  const chatkit = document.getElementById('chatkit');

  // Configure
  await chatkit.setOptions({
    api: {
      url: 'http://localhost:3000/chatkit',
      domainKey: 'dk_your_domain_key'
    },
    theme: 'light'
  });

  // Listen for events
  chatkit.addEventListener('chatkit.ready', () => {
    console.log('ChatKit ready!');
  });

  chatkit.addEventListener('chatkit.error', (event) => {
    console.error('Error:', event.detail.error);
  });

  // Send message
  await chatkit.sendUserMessage({ text: 'Hello!' });
</script>

See Frontend Integration Guide for complete documentation and examples.

SDK Integration Guide

ChatKit requires integration with both frontend and backend components. Here are quick examples to get you started:

Frontend Integration (React)

Quick React component example:

import { ChatKit } from '@openai/chatkit-react';

function App() {
  return (
    <ChatKit
      api={{
        getClientSecret: async () => {
          // Call your backend to get a session token
          const res = await fetch('/api/chatkit/session');
          const { client_secret } = await res.json();
          return client_secret;
        }
      }}
      theme="light"
      startScreen={{
        greeting: "Hello! How can I help you today?",
        prompts: ["Tell me a joke", "What can you do?"]
      }}
    />
  );
}

Backend Integration (Express)

Quick backend example for session creation:

import express from 'express';

const app = express();

app.post('/api/chatkit/session', async (req, res) => {
  const response = await fetch('https://api.openai.com/v1/chatkit/sessions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
      'OpenAI-Beta': 'chatkit_beta=v1',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      workflow: { id: process.env.CHATKIT_WORKFLOW_ID },
      user: req.body.user || 'anonymous'
    })
  });

  const data = await response.json();
  res.json({ client_secret: data.client_secret });
});

app.listen(3000);

Backend Integration (Next.js)

Quick Next.js API route example:

// app/api/chatkit/session/route.ts
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  const body = await request.json();

  const response = await fetch('https://api.openai.com/v1/chatkit/sessions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
      'OpenAI-Beta': 'chatkit_beta=v1',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      workflow: { id: process.env.CHATKIT_WORKFLOW_ID },
      user: body.user || 'anonymous'
    })
  });

  const data = await response.json();
  return NextResponse.json({ client_secret: data.client_secret });
}

Complete SDK Documentation

For comprehensive SDK integration including TypeScript types, error handling, advanced patterns, and testing:

Full SDK Integration Guide

CLI Discovery Commands

Quickly access examples and documentation via CLI:

# View SDK integration details
harness sdk openai-chatkit

# Frontend examples
harness example openai-chatkit:with-widgets

# Backend examples
harness example openai-chatkit:with-backend

# Interactive tutorial
harness tutorial openai-chatkit

# List all templates
harness templates openai-chatkit

Backend Integration

ChatKit requires a backend server to create sessions and handle authentication. You can build your backend in TypeScript using direct API calls - no Python required!

Quick Example

// Express backend for ChatKit
app.post('/api/chatkit/session', async (req, res) => {
  const response = await fetch('https://api.openai.com/v1/chatkit/sessions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
      'OpenAI-Beta': 'chatkit_beta=v1',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      workflow: { id: process.env.CHATKIT_WORKFLOW_ID },
      user: 'user-id-here',
    }),
  });

  const { client_secret } = await response.json();
  res.json({ client_secret });
});

Testing Support

For testing, use the built-in mock server:

import { BackendProtocolHelpers } from '@wavespec/adapter-openai-chatkit';

const server = BackendProtocolHelpers.createMockServer({
  port: 3000,
  domainKey: 'dk_test_123',
  handlers: {
    'message': async (req) => [
      { type: 'response.start', data: {} },
      { type: 'response.text', data: { text: 'Hello!' } },
      { type: 'response.end', data: {} }
    ]
  }
});

await server.start();

Learn More

For comprehensive backend documentation including session management, SSE streaming, and production patterns, see the Secure Integration Examples.

VCR Testing

The ChatKit adapter supports VCR cassette recording and replay through the harness CLI. See harness VCR documentation for usage.

Operations

| Operation | Description | |-----------|-------------| | set_options | Configure ChatKit instance | | focus_composer | Focus the message input | | set_thread | Switch to a thread | | send_message | Send a user message | | set_composer | Set draft without sending | | fetch_updates | Manually fetch updates | | send_action | Send custom widget action |

Events

The adapter translates ChatKit DOM CustomEvents to WaveSpec lifecycle events:

| ChatKit Event | WaveSpec Event | |--------------|----------------| | chatkit.ready | component_ready | | chatkit.error | error | | chatkit.response.start | response_start | | chatkit.response.end | response_end | | chatkit.thread.change | thread_change | | chatkit.thread.load.start | thread_load_start | | chatkit.thread.load.end | thread_load_end | | chatkit.log | diagnostic |

Quick Start with Templates

Get started quickly using pre-built test templates with the WaveSpec harness:

# List available templates
harness templates chatkit

# Generate an example test
harness example chatkit:init

# Run the test
harness run test.yaml

Available Templates

  • init - Minimal hosted integration using OpenAI-hosted backend
  • basic - Custom backend with domain key authentication
  • with-widgets - Widget rendering and interaction testing
  • with-backend - Full backend integration with file uploads

Each template provides a complete, runnable example that you can customize for your needs.

Documentation

Comprehensive guides to help you get the most out of ChatKit:

Security (Read This First!)

  • Security Guide - Comprehensive security documentation covering secure proxy pattern, domain allowlist, token refresh, and production deployment
  • Troubleshooting Guide - Common security issues and solutions with debugging tips
  • Secure Backend Examples - Working backend implementations (Express, Next.js, FastAPI)

Getting Started

  • Getting Started Guide - Complete setup guide with decision tree for choosing hosted vs custom backend, 5-minute quickstart, and troubleshooting

SDK Integration

  • SDK Integration Guide - Complete guide for using the adapter programmatically from TypeScript/JavaScript, including API reference, configuration examples, error handling, and testing patterns

Frontend Integration

Configuration & Operations

  • Configuration Reference - Complete reference for all configuration options including API config, theme customization, UI configuration, event callbacks, and internationalization (100+ locales)
  • Operations Guide - Detailed documentation for all 7 adapter operations with examples and error handling

Advanced Topics

Examples

  • Examples Directory - Five complete, runnable TypeScript examples:
    • basic-chat.ts - Simple message sending and response handling
    • widget-interaction.ts - Widget rendering and action triggers
    • file-upload.ts - File attachment handling (two-phase and direct)
    • multi-thread.ts - Thread creation and management
    • error-handling.ts - Error recovery patterns and retry logic

Run any example with: tsx docs/examples/basic-chat.ts

Development Status

🚧 In Development - Phase 1 implementation in progress

License

MIT