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

@vikaskalla/sentra-chat-widget

v1.0.5

Published

Reusable chat widget for Sentra Platform - Embed Sentra AI chat interface in your applications

Readme

@vikaskalla/sentra-chat-widget

A reusable React chat widget for integrating Sentra Platform's AI chat into your applications. It provides a full chat UI with message history, execution timeline, optional HITL, and workflow UI nodes in a full-screen modal.

Features

  • Easy integration: Pass sentraUrl, userId, and projectId.
  • Chat UI aligned with Sentra app: Message list, typing indicator, execution timeline, and HITL inline card match packages/ui.
  • New conversation: Header button starts a fresh session; optional onNewConversation(newConversationId) for the host to update session/conversation display.
  • Stream auth: When using accessToken, the widget appends it as a query param for the EventSource stream URL so the API gateway can authenticate GET stream requests.
  • Full theming: All components use semantic tokens (no hardcoded colors); host provides CSS variables for light/dark and brand.
  • Rich responses: Tables, cards, lists, markdown, HTML, and JSON.
  • Workflow UI: Full-screen modal for workflow UI nodes via SSE.
  • TypeScript: Full type support and exported types.

Alignment with Sentra UI

The chat UI matches packages/ui (main Sentra app):

  • Message list: Scroll-to-bottom, empty state, message ordering.
  • Typing indicator: Left-aligned bubble with "Thinking..." and bouncing dots.
  • Execution timeline: Per-message collapsible timeline (routing, tool calls, completion) from the query stream.
  • HITL: Inline amber card with "Respond"; use onHITLRespond to handle (e.g. open modal and call HITL API).

MessageList and MessageBubble use the same props and event shapes as the UI package (messageEvents, executionEvents, onHITLRespond).

Installation

npm install @vikaskalla/sentra-chat-widget
# or
yarn add @vikaskalla/sentra-chat-widget
# or
pnpm add @vikaskalla/sentra-chat-widget

Quick Start

import { ChatWidget } from '@vikaskalla/sentra-chat-widget';

function App() {
  return (
    <div style={{ height: '100vh' }}>
      <ChatWidget
        config={{
          sentraUrl: 'http://localhost:3011',
          userId: 'user-123',
          projectId: 'project-456',
          sessionId: 'session-789',
          features: { chatHistory: true, workflowUI: true, hitl: true },
        }}
      />
    </div>
  );
}

The widget connects to the workflow SSE stream automatically when userId is set and the gateway reports workflow events capability (GET /health/readycapabilities.workflowEvents). If the workflow service is not running, the widget skips the relay and continues without workflow UI updates (no user-facing error). Set features.workflowUI: false to disable workflow events entirely.

ChatConfig

The widget accepts a single config prop of type ChatConfig:

| Property | Type | Default | Description | |----------|------|---------|-------------| | sentraUrl | string | required | Base URL of Sentra (e.g. API gateway). | | userId | string | required | User identifier. | | projectId | string | required | Project ID. | | sessionId | string | sess_${Date.now()} | Session for conversation grouping. | | accessToken | string | - | Bearer token for API auth (see Authentication). | | features | ChatFeatures | see below | Feature flags for optional UI. | | className | string | '' | Extra CSS classes for the container. | | onError | (error: Error) => void | - | Error callback. | | workflowUIContainer | HTMLElement or null | - | Container for workflow UI. | | workflowUIRightOffset | number | 500 | Right offset in px for workflow UI. | | workflowUIDisplayMode | 'carousel' or 'vertical' | 'vertical' | UI nodes: carousel or vertical list. | | onHITLRespond | (hitlRequestId, agentId, eventData?) => void | - | Called when user clicks "Respond" on HITL card (when features.hitl is false or for custom handling). | | onNewConversation | (newConversationId?: string) => void | - | Called when user starts a new conversation (e.g. host can update sessionId for display). | | timelineAutoCollapse | boolean | false | When true, auto-collapse execution timeline when loading completes (matches packages/ui). |

Feature flags (features)

| Flag | Default | Description | |------|---------|-------------| | chatHistory | true | Show chat history panel (conversation list). | | workflowUI | true | Enable workflow events relay and full-screen workflow modal. | | hitl | true | Use built-in HITL modal; when false, use onHITLRespond callback only. | | debugPanel | false | Show execution debug panel (future). | | documents | false | Show documents panel (future). | | voice | false | Enable voice assistant (future). |

The widget header includes a New conversation button. Clicking it starts a fresh session: creates a new conversation via the API, clears the message list, and optionally notifies the host via onNewConversation(newConversationId) so the host can update session/conversation display (aligned with main Sentra Chat UI).

Recent updates (gaps addressed)

  • API gateway only: All traffic (chat, query stream, workflow events relay) is routed via sentraUrl (API gateway). The workflowServiceUrl prop was removed; the widget no longer connects directly to any backend service.
  • Theming: Replaced all hardcoded gray/blue/red/white with semantic tokens (bg-card, border-border, text-foreground, text-muted-foreground, bg-primary, text-destructive, etc.) in ChatWidget, MessageList, MessageBubble, TypingIndicator, ResponseRenderer, TableResponse, ListResponse, CardResponse, ErrorBoundary, WorkflowFullScreenModal, and UINodeRenderer.
  • New conversation: Header "New conversation" button; onNewConversation(newConversationId) callback for host to refresh session/conversation display.
  • Stream auth: EventSource cannot send Authorization; widget appends access_token to the stream URL when accessToken is set so the API gateway can authenticate the GET stream (gateway must accept token from query for /api/v1/query/stream/*).
  • Conversation/session display: Header shows truncated conversation ID and session ID for parity with main Sentra Chat UI.

Authentication

  • Same origin: Omit accessToken; cookies are sent automatically.
  • Cross-origin or PAT: Set accessToken; the widget sends Authorization: Bearer <token>. The query stream (EventSource) cannot send custom headers; use same-origin or a proxy for token-based streaming.

Env example (Vite):

VITE_SENTRA_ACCESS_TOKEN=your-token
VITE_SENTRA_URL=https://api.sentra.example.com
<ChatWidget
  config={{
    sentraUrl: import.meta.env.VITE_SENTRA_URL,
    userId: 'user-123',
    projectId: 'project-456',
    accessToken: import.meta.env.VITE_SENTRA_ACCESS_TOKEN,
    features: { chatHistory: true, workflowUI: true, hitl: true },
  }}
/>

Use REACT_APP_* or NEXT_PUBLIC_* for CRA/Next.js. Prefer server-side or build-time injection in production.

Usage Examples

With error handling:

<ChatWidget
  config={{
    sentraUrl: 'https://api.sentra.example.com',
    userId: 'user-123',
    projectId: 'project-456',
    onError: (err) => console.error(err),
  }}
/>

How It Works

Chat messages
Messages are rendered by MessageList and MessageBubble. The widget streams queries when possible; stream events are pushed into messageEvents so the execution timeline and typing state stay in sync with packages/ui.

Routing
All API traffic (chat, query stream, workflow events) is sent to sentraUrl (the API gateway). The gateway proxies to the appropriate backend services. Set sentraUrl to your API gateway base URL (e.g. http://localhost:3011).

Required vs optional services
Core chat requires the API gateway, execution service, agent service, and (if using PAT) configuration service. The workflow service is optional: when it is not running, chat works but workflow UI events (e.g. node completion modal) are unavailable. The widget uses the gateway’s readiness endpoint (GET /health/ready) to discover capabilities.workflowEvents and only connects to the workflow events relay when available, avoiding 500s or connection errors for that optional feature.

Workflow UI nodes
When workflow events are enabled and the gateway reports workflowEvents: true, the widget opens an SSE connection to {sentraUrl}/api/v1/workflows/events/relay?userId={userId}. It listens for ui.node.started, ui.node.completed, and node.completed, and opens the full-screen workflow modal when UI node events arrive. Node results are kept for data binding (e.g. ${tool-xxx.output}). If the connection fails, the widget retries with exponential backoff (up to 5 attempts) then continues without workflow UI updates.

Response formats
Assistant content can be plain text, markdown, HTML, or JSON. Structured JSON with type: table, list, or card is rendered with the corresponding component.

Using Individual Components

Contracts match packages/ui:

  • MessageList: messages, isLoading, optional messageEvents (Map<id, ExecutionEvent[]>), optional onHITLRespond.
  • MessageBubble: message, optional executionEvents, optional onHITLRespond.
import {
  MessageList,
  MessageBubble,
  TypingIndicator,
  ResponseRenderer,
  WorkflowFullScreenModal,
  ChatService
} from '@vikaskalla/sentra-chat-widget';

function CustomChat() {
  const [messages, setMessages] = useState([]);
  const [messageEvents, setMessageEvents] = useState(new Map());
  return (
    <MessageList
      messages={messages}
      isLoading={loading}
      messageEvents={messageEvents}
      onHITLRespond={(id, agentId, data) => {}}
    />
  );
}

Service only:

import { ChatService } from '@vikaskalla/sentra-chat-widget';

const service = new ChatService('https://api.sentra.example.com');
const result = await service.sendQuery('Hello', 'user-123', 'project-456');
const messages = await service.getMessages(conversationId);

Styling / Theming

The widget is fully themeable via CSS variables. The host app must use Tailwind and define the same design tokens as the Sentra app (or shadcn-style theme):

  • Surfaces: --background, --card, --foreground, --card-foreground
  • Borders / inputs: --border, --input, --ring
  • Primary: --primary, --primary-foreground
  • Muted: --muted, --muted-foreground
  • Accent: --accent, --accent-foreground
  • Destructive: --destructive, --destructive-foreground

All widget components (ChatWidget, MessageList, MessageBubble, TypingIndicator, ResponseRenderer, TableResponse, ListResponse, CardResponse, ErrorBoundary, WorkflowFullScreenModal, UINodeRenderer) use these semantic classes only (e.g. bg-primary, bg-card, border-border, text-muted-foreground, bg-destructive/10). No hardcoded gray/blue/red; the widget inherits the host’s theme and works with light/dark when the host toggles the token values.

TypeScript

import type {
  ChatConfig,
  ChatFeatures,
  ChatMessage,
  Conversation,
  WorkflowDataItem,
  ExecutionEvent
} from '@vikaskalla/sentra-chat-widget';

Requirements

  • React 18+
  • Sentra Platform instance

API Endpoints

  • POST /api/v1/query – send query
  • POST /api/v1/query/stream/init – start query stream
  • GET /api/v1/chat/conversations, POST /api/v1/chat/conversations
  • GET /api/v1/chat/conversations/:id/messages
  • POST /api/v1/chat/conversations/:id/end
  • GET /api/v1/workflows/events/relay?userId={userId} – workflow SSE (auto-connected)

Error Handling

  • Network and API errors surface in the chat and trigger onError when provided.
  • Error messages are appended to the conversation.

Browser Support

Chrome, Firefox, Safari, Edge (latest).

Development

pnpm install
pnpm build
pnpm dev
pnpm type-check
pnpm lint

License

MIT

Support

Sentra Platform repository

Contributing

See the main repository for guidelines.