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

@object-ui/plugin-chatbot

v6.2.0

Published

Chatbot interface plugin for Object UI

Readme

@object-ui/plugin-chatbot

Chatbot interface plugin for Object UI with full AI SDUI support, built on Vercel AI Elements (MIT) and shadcn/ui (MIT).

Why AI Elements? They give us a production-grade, shadcn-style chat surface — conversation, message bubbles, streaming reasoning, tool calls, sources, code blocks, suggestions — that already matches our Tailwind 4 design tokens. We vendor them into src/elements/ so we can ship without a network dep, and we wrap them inside ChatbotEnhanced to keep the public ObjectUI prop API stable. See Architecture below.

Installation

npm install @object-ui/plugin-chatbot

Usage

Basic (Local/Demo Mode)

import { Chatbot } from '@object-ui/plugin-chatbot';

function App() {
  const [messages, setMessages] = useState([
    {
      id: '1',
      role: 'assistant',
      content: 'Hello! How can I help you today?'
    }
  ]);

  const handleSend = (content: string) => {
    const newMessage = {
      id: Date.now().toString(),
      role: 'user',
      content
    };
    setMessages([...messages, newMessage]);
  };

  return (
    <Chatbot
      messages={messages}
      onSendMessage={handleSend}
      placeholder="Type your message..."
    />
  );
}

AI Streaming Mode (service-ai)

When api is set in the schema, the chatbot connects to a backend SSE endpoint using @ai-sdk/react v3 (Vercel UI Message Stream protocol) for streaming, tool-calling, and production-grade chat:

import '@object-ui/plugin-chatbot';

const schema = {
  type: 'chatbot',
  api: '/api/v1/ai/chat',
  model: 'gpt-4o',
  systemPrompt: 'You are a helpful assistant.',
  streamingEnabled: true,
  conversationId: 'conv-123',
  messages: [
    { id: '1', role: 'assistant', content: 'Hello! Ask me anything.' }
  ],
  placeholder: 'Type your message...',
};

Using the useObjectChat Hook

For custom integrations, you can use the useObjectChat hook directly:

import { useObjectChat } from '@object-ui/plugin-chatbot';

function MyChat() {
  const {
    messages,
    isLoading,
    error,
    sendMessage,
    stop,
    reload,
    clear,
    isApiMode,
  } = useObjectChat({
    api: '/api/v1/ai/chat',
    model: 'gpt-4o',
    systemPrompt: 'You are helpful.',
  });

  return (
    <div>
      {messages.map(msg => (
        <div key={msg.id}>{msg.content}</div>
      ))}
      {isLoading && <button onClick={stop}>Stop</button>}
      {error && <button onClick={reload}>Retry</button>}
    </div>
  );
}

Schema-Driven Usage

Discovering Backend Agents

Use useAgents to fetch the list of agents exposed by @objectstack/service-ai at GET {apiBase}/agents. This is what the global console FAB uses to populate its in-header agent picker:

import { useAgents } from '@object-ui/plugin-chatbot';

function AgentPicker() {
  const { agents, isLoading, error } = useAgents({
    apiBase: 'http://localhost:3000/api/v1/ai',
    // Optional fallback list shown when the backend is unreachable
    fallback: [{ name: 'data_chat', label: 'Data Chat' }],
  });

  if (isLoading) return <span>Loading agents…</span>;
  if (error) return <span>Backend unreachable</span>;

  return (
    <select>
      {agents.map(a => (
        <option key={a.name} value={a.name}>{a.label}</option>
      ))}
    </select>
  );
}

Each agent's chat endpoint is POST {apiBase}/agents/{name}/chat — pass that URL as the api option to useObjectChat to talk to it.

Console Integration

The console (@object-ui/app-shell) auto-mounts a global floating chatbot when useDiscovery().isAiEnabled is true. Configure the backend in your console .env:

# AI service endpoint (defaults to ${VITE_SERVER_URL}/api/v1/ai when unset)
VITE_AI_BASE_URL=http://localhost:3000/api/v1/ai
# Default agent to select on first open (must match an agent name returned
# by GET ${VITE_AI_BASE_URL}/agents)
VITE_AI_DEFAULT_AGENT=sales_copilot

The picker lets the user switch agents at runtime; switching transparently remounts the chat hook against the new agent's /chat endpoint.

This plugin automatically registers with ObjectUI's component registry when imported:

import '@object-ui/plugin-chatbot';

// Local/demo mode
const demoSchema = {
  type: 'chatbot',
  messages: [
    { id: '1', role: 'assistant', content: 'Hello!' }
  ],
  placeholder: 'Type your message...',
  autoResponse: true,
};

// AI streaming mode
const aiSchema = {
  type: 'chatbot',
  api: '/api/v1/ai/chat',
  model: 'gpt-4o',
  systemPrompt: 'You are a helpful assistant.',
  streamingEnabled: true,
  messages: [],
  placeholder: 'Ask the AI...',
};

Two Operating Modes

| Feature | Local/Demo Mode | AI Streaming Mode | |---------|----------------|-------------------| | api | Not set | Set to SSE endpoint | | Responses | Auto-response (configurable) | Real AI streaming via SSE | | Streaming | Simulated | Full SSE streaming | | Tool calling | N/A | Supported via vercel/ai | | Stop/Reload | Stop cancels timer | Stop interrupts stream | | Backend | None required | service-ai (IAIService) |

Compatibility

  • React: 18.x or 19.x
  • Node.js: ≥ 18
  • TypeScript: ≥ 5.0 (strict mode)
  • @objectstack/spec: ^3.3.0
  • @objectstack/client: ^3.3.0
  • Tailwind CSS: ≥ 3.4 (for packages with UI)

Links

Architecture

Internally the chatbot is composed from three layers:

┌─────────────────────────────────────────────────────┐
│  ChatbotEnhanced (public surface, stable props)     │
│  ├─ Conversation / Message  (AI Elements)           │
│  ├─ PromptInput  (AI Elements)                      │
│  └─ Suggestion / Reasoning / Tool  (AI Elements)    │
├─────────────────────────────────────────────────────┤
│  src/elements/                                      │
│  Vendored Vercel AI Elements + missing shadcn       │
│  primitives (button-group, input-group). Rewritten  │
│  to import from `@object-ui/components`. Do NOT     │
│  edit — re-sync from registry.ai-sdk.dev.           │
├─────────────────────────────────────────────────────┤
│  @object-ui/components (shadcn + Tailwind 4)        │
└─────────────────────────────────────────────────────┘

The vendored components are also re-exported under a namespace for advanced users who want to compose their own chat surface:

import { AIElements } from '@object-ui/plugin-chatbot';

<AIElements.Conversation>
  <AIElements.ConversationContent>
    <AIElements.Message from="assistant">
      <AIElements.MessageContent>Hello.</AIElements.MessageContent>
    </AIElements.Message>
  </AIElements.ConversationContent>
</AIElements.Conversation>;

Message mapping helpers

If you wire @ai-sdk/react's useChat() directly and want to render its UIMessage[] with <ChatbotEnhanced>, use the exported mappers instead of writing your own — they handle parts: [{ type: 'text' | 'reasoning' | 'tool-*' | 'source-*' }], the streaming-cursor flag, and the legacy msg.toolInvocations fallback:

import { useChat } from '@ai-sdk/react';
import {
  ChatbotEnhanced,
  uiMessagesToChatMessages,
} from '@object-ui/plugin-chatbot';

function MyChat() {
  const { messages, status } = useChat({ api: '/api/chat' });
  const isStreaming = status === 'streaming' || status === 'submitted';
  return (
    <ChatbotEnhanced
      messages={uiMessagesToChatMessages(messages, { isStreaming })}
      onSend={/* … */}
    />
  );
}

uiMessageToChatMessage(msg, { streaming }) is the single-message variant. Both are also used internally by useObjectChat, so the mapping logic stays consistent across direct and managed usage.

Bundle considerations

This package depends on streamdown, shiki, mermaid, and katex for code/markdown rendering. Together they weigh ~20 MB minified.

In host apps that don't always show the chat panel (e.g. Studio's opt-in AI sidebar), import this package via React.lazy so the heavy chunks only download when the panel actually opens. See apps/studio/src/routes/__root.tsx for the reference pattern, and apps/studio/vite.config.ts for the manualChunks rules that keep the chat-only deps in dedicated, lazy-loadable chunks.

License

MIT © ObjectStack Inc.

Third-party code shipped under src/elements/:

  • Vercel AI Elements — MIT © Vercel, Inc.
  • shadcn/ui primitives (button-group, input-group) — MIT © shadcn.