@binddk33/secondbrain-chat-sdk
v0.3.0
Published
Vendor-neutral JavaScript SDK for streaming chat from SecondBrain Enterprise Chat API
Maintainers
Readme
SecondBrain Chat SDK
A vendor-neutral JavaScript SDK for streaming chat responses from the SecondBrain Enterprise Chat API. Works with React, plain HTML, WordPress, PHP, and any frontend framework.
Published as: @binddk33/secondbrain-chat-sdk on npm
Features
- ⚡ Streaming responses with Server-Sent Events (SSE)
- 🎯 Minimal integration - one config object, one function call
- 🔌 Framework agnostic - React hooks, UMD bundle, or raw client
- 🔒 Token hygiene - supports relay servers for legacy CMS
- 📦 Zero external dependencies for the core client
- 🎨 Optional pre-built widget or headless mode
Quick Start
Installation
npm install @binddk33/secondbrain-chat-sdkor
yarn add @binddk33/secondbrain-chat-sdkor
pnpm add @binddk33/secondbrain-chat-sdkReact / Next.js
Option 1: Floating Button (Recommended)
import { SbProvider, FloatingChatButton } from "@binddk33/secondbrain-chat-sdk/react";
function App() {
return (
<SbProvider
config={{
baseUrl: "https://dev.insurance.secondbrain.global",
enterpriseUuid: "97e6f460-b779-4568-b34f-b5ae32d7a1f8",
memberUuid: "a05a2819-7f79-470a-b36b-9f7516d92cd8",
conversationTitle: "Support Chat",
getAccessToken: async () => {
const res = await fetch("/api/sb-token");
return res.text();
},
}}
>
{/* Your app content */}
<YourAppContent />
{/* Floating chat button - appears in bottom-right corner */}
<FloatingChatButton
title="Chat with us"
buttonColor="#2563eb"
/>
</SbProvider>
);
}Option 2: Inline Widget
import { SbProvider, ChatWidget } from "@binddk33/secondbrain-chat-sdk/react";
function App() {
return (
<SbProvider
config={{
baseUrl: "https://dev.insurance.secondbrain.global",
enterpriseUuid: "97e6f460-b779-4568-b34f-b5ae32d7a1f8",
memberUuid: "a05a2819-7f79-470a-b36b-9f7516d92cd8",
conversationTitle: "Support Chat",
getAccessToken: async () => {
const res = await fetch("/api/sb-token");
return res.text();
},
}}
>
<ChatWidget
title="Support Chat"
placeholder="Ask about policy coverage..."
/>
</SbProvider>
);
}Plain HTML / WordPress
Option 1: Floating Button
<script src="https://unpkg.com/@binddk33/secondbrain-chat-sdk/dist/umd/sbchat.umd.js"></script>
<script>
SecondBrain.init({
baseUrl: "https://dev.insurance.secondbrain.global",
enterpriseUuid: "97e6f460-b779-4568-b34f-b5ae32d7a1f8",
memberUuid: "a05a2819-7f79-470a-b36b-9f7516d92cd8",
conversationTitle: "Support Chat",
getAccessToken: () => fetch("/api/sb-token").then((r) => r.text()),
title: "Chat with us",
buttonColor: "#2563eb",
});
</script>Option 2: Inline Widget
<div id="sb-chat"></div>
<script src="https://unpkg.com/@binddk33/secondbrain-chat-sdk/dist/umd/sbchat.umd.js"></script>
<script>
SecondBrain.mount("#sb-chat", {
baseUrl: "https://dev.insurance.secondbrain.global",
enterpriseUuid: "97e6f460-b779-4568-b34f-b5ae32d7a1f8",
memberUuid: "a05a2819-7f79-470a-b36b-9f7516d92cd8",
conversationTitle: "Support Chat",
getAccessToken: () => fetch("/api/sb-token").then((r) => r.text()),
title: "Support Chat",
placeholder: "Ask a question...",
});
</script>Headless Mode (Custom UI)
import { SbProvider, useChat } from "@binddk33/secondbrain-chat-sdk/react";
function CustomChat() {
const { messages, streaming, send, clear, ready } = useChat();
return (
<div>
{!ready && <div>Initializing...</div>}
{messages.map((msg) => (
<div key={msg.id} className={msg.role}>
{msg.text}
</div>
))}
<input
onKeyDown={(e) => {
if (e.key === "Enter" && !streaming) {
send(e.currentTarget.value);
e.currentTarget.value = "";
}
}}
disabled={!ready || streaming}
/>
<button onClick={clear}>Clear</button>
</div>
);
}
function App() {
return (
<SbProvider config={{ /* ... */ }}>
<CustomChat />
</SbProvider>
);
}Raw Client (No Framework)
import { SbClient } from "@binddk33/secondbrain-chat-sdk";
const client = new SbClient({
baseUrl: "https://dev.insurance.secondbrain.global",
enterpriseUuid: "97e6f460-b779-4568-b34f-b5ae32d7a1f8",
memberUuid: "a05a2819-7f79-470a-b36b-9f7516d92cd8",
conversationTitle: "Support Chat",
getAccessToken: async () => "your-token",
});
// Wait for conversation to initialize
await client.ready;
// Send a message and stream the response
for await (const event of client.send({
query: "What does my policy cover?",
citations: true,
})) {
if (event.type === "delta") {
process.stdout.write(event.value);
} else if (event.type === "log") {
console.log(`[LOG] ${event.value}`);
} else if (event.type === "error") {
console.error(`[ERROR] ${event.value}`);
}
}API Reference
Configuration (SbConfig)
| Property | Type | Required | Description |
| --------------------- | ----------------------- | -------- | ------------------------------------------- |
| baseUrl | string | ✓ | SecondBrain API base URL |
| enterpriseUuid | string | ✓ | Your enterprise UUID |
| memberUuid | string | ✓ | Member UUID (identifies the end user) |
| conversationTitle | string | | Optional title for the conversation |
| getAccessToken | () => Promise<string> | | Async function returning auth token |
| origin | string | | Optional Origin header for CORS |
| fetchFn | typeof fetch | | Custom fetch implementation |
| onEvent | (evt) => void | | Debug callback for all stream events |
Send Arguments (SendArgs)
| Property | Type | Required | Description |
| ----------- | --------- | -------- | --------------------------------- |
| query | string | ✓ | User's question |
| citations | boolean | | Include citations (default: true) |
Stream Events
| Event | Properties | Description |
| ---------- | --------------- | ------------------------- |
| start | — | Stream has started |
| delta | value: string | Text chunk from assistant |
| log | value: string | Status/progress update |
| error | value: string | Error message |
| complete | — | Stream has finished |
React Components
<SbProvider>
Wraps your app and provides the SecondBrain client to child components.
<SbProvider config={sbConfig}>{children}</SbProvider><FloatingChatButton>
Fixed-position chat button that appears in the bottom-right corner.
<FloatingChatButton
title="Chat with us"
placeholder="Ask a question..."
buttonColor="#2563eb"
buttonSize="60px"
bottom="24px"
right="24px"
chatWidth="400px"
chatMaxHeight="600px"
showLog={true}
markdown={true}
defaultOpen={false}
/><ChatWidget>
Pre-built inline chat widget with messages display, input, and send button.
<ChatWidget
placeholder="Ask a question..."
title="Support Chat"
showLog={true}
markdown={true}
className="my-chat"
style={{ maxWidth: "500px" }}
/>useChat(options?)
Hook for building custom chat UIs. Must be used within <SbProvider>.
const {
messages, // ChatMessage[] - chat history
streaming, // boolean - currently streaming
log, // string | null - status messages
error, // string | null - error messages
ready, // boolean - client initialized
conversationUuid, // string | null - conversation ID
send, // (query: string) => Promise<void>
clear, // () => void - clear messages
} = useChat({
onEvent: (event) => console.log(event),
onError: (error) => console.error(error),
});useSbContext()
Access the client instance and initialization state.
const { client, ready, initError } = useSbContext();UMD / Script Tag API
SecondBrain.init(options)
Initialize a floating chat button (easiest way to add chat to any site).
const widget = SecondBrain.init({
baseUrl: "https://dev.insurance.secondbrain.global",
enterpriseUuid: "...",
memberUuid: "...",
getAccessToken: () => fetch("/api/token").then(r => r.text()),
title: "Chat with us",
buttonColor: "#2563eb",
});
// Destroy the widget
widget.destroy();SecondBrain.mount(selector, options)
Mount an inline chat widget into a DOM element.
const widget = SecondBrain.mount("#chat", {
baseUrl: "https://dev.insurance.secondbrain.global",
enterpriseUuid: "...",
memberUuid: "...",
getAccessToken: () => fetch("/api/token").then(r => r.text()),
title: "Support Chat",
placeholder: "Ask a question...",
});
// Destroy the widget
widget.destroy();SecondBrain.createClient(config)
Create a raw client for custom integrations.
const client = SecondBrain.createClient(config);
await client.ready;
for await (const event of client.send({ query: "Hello" })) {
console.log(event);
}Server Relays
For PHP, WordPress, or environments where you can't expose tokens to the client, use a relay server.
Node.js Relay
See examples/relay-node/server.ts
cd examples/relay-node
npm install
SECONDBRAIN_SERVICE_TOKEN=xxx npm run devPHP Relay
See examples/relay-php/relay.php
cd examples/relay-php
SECONDBRAIN_SERVICE_TOKEN=xxx php -S localhost:3000 relay.phpSecurity Best Practices
- Never expose enterprise/tenant IDs from untrusted user input
- Enforce Authorization on the server side
- Use short-lived tokens with minimal scopes
- For legacy CMS, use the proxy pattern - keep tokens server-side
Development
Setup
# Install dependencies
npm install
# Build library
npm run build
# Type check
npm run typecheckRunning Examples
# Run React example (with relay)
cd examples/relay-node && npm install && SECONDBRAIN_SERVICE_TOKEN=xxx npm run dev &
cd examples/react-app && npm install && npm run devBuild Commands
# Build ES modules and CommonJS
npm run build
# Build UMD bundle only
npm run build:umd
# Type check without emitting files
npm run typecheckProject Structure
secondbrain-sdk/
├── src/
│ ├── core/ # Pure business logic (no React/UI)
│ │ ├── types.ts # Type definitions
│ │ ├── client.ts # SbClient - conversation & streaming
│ │ ├── sse.ts # SSE parser
│ │ └── index.ts # Core exports
│ ├── react/ # React integration
│ │ ├── context.tsx # Provider & context
│ │ ├── hooks/ # React hooks (useChat)
│ │ ├── components/ # ChatWidget, FloatingChatButton
│ │ └── index.tsx # React exports
│ ├── umd/ # Browser global
│ │ └── index.tsx # UMD build for script tags
│ ├── index.ts # Main entrypoint → core
│ ├── react.tsx # React entrypoint → react/
│ ├── umd.tsx # UMD entrypoint → umd/
│ └── README.md # Architecture documentation
├── examples/
│ ├── react-app/ # React/Vite example
│ ├── html-vanilla/ # Plain HTML examples
│ ├── relay-node/ # Node.js relay server
│ └── relay-php/ # PHP relay script
├── dist/ # Built output (generated)
│ ├── index.js # ES module build
│ ├── index.cjs # CommonJS build
│ ├── react.js # React ES module
│ ├── react.cjs # React CommonJS
│ ├── *.d.ts # TypeScript declarations
│ └── umd/ # UMD bundle for script tags
└── package.json # Package configurationSee src/README.md for detailed architecture documentation.
Publishing
To npm
This SDK is published to npm as @binddk33/secondbrain-chat-sdk.
Current Version: 0.1.0 Package URL: https://www.npmjs.com/package/@binddk33/secondbrain-chat-sdk
Publishing New Versions
- Login to npm via CLI:
npm login
Publishing Steps
Update Version: Update the version in package.json following semantic versioning:
npm version patch # for bug fixes (0.1.0 -> 0.1.1) npm version minor # for new features (0.1.0 -> 0.2.0) npm version major # for breaking changes (0.1.0 -> 1.0.0)Build the Package: The
prepublishOnlyscript will automatically build before publishing:npm run buildPublish to npm:
# For first-time public scoped package npm publish --access public # For subsequent publishes npm publishVerify: Check your package at
https://www.npmjs.com/package/@binddk33/secondbrain-chat-sdk
Publishing to a Private Registry
If you want to use a private npm registry (like GitHub Packages or Verdaccio):
Configure npm registry in package.json:
{ "publishConfig": { "registry": "https://npm.pkg.github.com" } }Authenticate with your registry:
npm login --registry=https://npm.pkg.github.comPublish:
npm publish
To CDN (unpkg/jsdelivr)
Once published to npm, the UMD bundle is automatically available via CDN:
<!-- unpkg -->
<script src="https://unpkg.com/@binddk33/secondbrain-chat-sdk@latest/dist/umd/sbchat.umd.js"></script>
<!-- jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/@binddk33/secondbrain-chat-sdk@latest/dist/umd/sbchat.umd.js"></script>Version Management
- Use
npm versioncommands to properly tag releases - Update README.md with any breaking changes
- Consider using conventional commits for clear changelogs
License
MIT
