Skip to content

smaramwbc/statewave-chat

Statewave Chat

CI npm License: Apache-2.0

Reusable chat packages for Statewave — the open-source memory runtime for AI agents. Build grounded, memory-backed chat experiences once and embed them anywhere.

Part of the Statewave ecosystem: Server · Python SDK · TypeScript SDK · Connectors · Docs · Examples · Website + demo · Admin

📋 Issues & feature requests: statewave/issues (centralized tracker)

What this is

This monorepo provides three packages that extract the proven chatbot architecture from statewave-web into a reusable, framework-agnostic chat platform. It handles retrieval across multiple Statewave subjects, structured grounded completions, citation validation, and optional conversation persistence — so that any application can add a memory-backed chat experience without reimplementing the engine.

It is not the Statewave server (that's statewave) or the TypeScript SDK (that's statewave-ts). It builds on both.

Packages

Package npm Description
@statewavedev/chat-core npm Framework-independent types, adapter interfaces, multi-subject retrieval engine, prompt construction, citation validation
@statewavedev/chat-react npm React provider, fine-grained hooks, and accessible unstyled UI components
@statewavedev/chat-widget npm Drop-in <StatewaveChat> component and mountStatewaveChat() for vanilla JS

Install

# React applications
npm install @statewavedev/chat-react @statewavedev/chat-core

# Drop-in widget (React or vanilla JS)
npm install @statewavedev/chat-widget

# Headless / framework-agnostic
npm install @statewavedev/chat-core

Quick start

Server route (Next.js API route, Express handler, etc.):

// app/api/chat/route.ts (Next.js App Router)
import { createStatewaveChatAdapter } from "@statewavedev/chat-core/server";
import { StatewaveClient } from "@statewavedev/sdk";
import { sendMessage } from "@statewavedev/chat-core";

const client = new StatewaveClient({ apiKey: process.env.STATEWAVE_API_KEY! });
const adapter = createStatewaveChatAdapter({
  client,
  completionFn: async (messages, opts) => {
    const resp = await openai.chat.completions.create({
      model: "gpt-4o",
      messages,
      signal: opts?.signal,
    });
    return { content: resp.choices[0].message.content ?? "" };
  },
});

React app (client-side, using a proxy adapter that calls your server route):

import { StatewaveChatProvider, MessageThread, ChatComposer, useChatMessages, useChatLoading, useSendMessage } from "@statewavedev/chat-react";

function MyApp() {
  return (
    <StatewaveChatProvider
      adapter={myProxyAdapter}
      readSubjects={["user:alice", "project:my-project"]}
      retrievalConfig={{ globalMaxTokens: 2000 }}
    >
      <Chat />
    </StatewaveChatProvider>
  );
}

function Chat() {
  const messages = useChatMessages();
  const isLoading = useChatLoading();
  const sendMessage = useSendMessage();
  return (
    <>
      <MessageThread messages={messages} isLoading={isLoading} />
      <ChatComposer onSend={sendMessage} isLoading={isLoading} />
    </>
  );
}

Drop-in widget (vanilla JS):

import { mountStatewaveChat } from "@statewavedev/chat-widget";

const { unmount } = mountStatewaveChat(
  document.getElementById("statewave-chat"),
  { adapter: myProxyAdapter, readSubjects: ["user:alice"], retrievalConfig: { globalMaxTokens: 2000 } }
);

Architecture

statewave-connectors (GitHub, Slack, Notion, …)
        ↓  ingest episodes
Statewave Server  ──  @statewavedev/sdk
        ↓  getContext / createEpisode
@statewavedev/chat-core  (server-side adapter)
        ↓  structured grounded completion
@statewavedev/chat-react / @statewavedev/chat-widget
        ↓
statewave-web · statewave-admin · your app

Key design constraints:

  • Global token budgetglobalMaxTokens is split evenly across subjects; items are merged in round-robin subject order and deduplicated before truncation
  • Prompt injection barrier — retrieved evidence is framed in <evidence> tags; connector content cannot override system instructions
  • Citation ownership — the model returns only opaque IDs (S1, S2, …); the server resolves them to full ChatCitation objects; model output never contains source URLs, titles, or memory IDs
  • Read/write subject isolationwriteSubject is never readable until after the first persisted turn
  • AbortSignal throughout — all async operations are cancellable without retry

See statewave-docs for the full design, subject naming conventions, and connector compatibility guide.

Development

git clone https://github.com/smaramwbc/statewave-chat.git
cd statewave-chat
pnpm install
pnpm -r typecheck
pnpm -r test
pnpm -r build

Requires Node.js ≥ 18 and pnpm ≥ 9.

Stack

Layer Technology
Language TypeScript 6, strict mode
Module format ESM ("type": "module")
Module resolution NodeNext
Testing Vitest
Versioning Changesets
Package manager pnpm (workspace)

Scripts

Command Description
pnpm -r typecheck TypeScript check across all packages
pnpm -r test Run tests across all packages
pnpm -r build Build all packages to dist/
pnpm -r lint ESLint across all packages
pnpm changeset Prepare a version bump
pnpm release Publish packages (CI only)

Ecosystem

Project Description
statewave Core server — API, domain model, DB, services
statewave-py pip install statewave
statewave-ts npm install @statewavedev/sdk
statewave-connectors @statewavedev/connectors-*
statewave-docs Architecture, API contracts, ADRs
statewave-examples Runnable examples
statewave-web Marketing site + embedded demo
statewave-admin Operator console

License

Apache-2.0

About

Reusable Statewave chat packages — chat-core, chat-react, chat-widget

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors