The B-Bot SDK (@beyond-bot-ai/sdk) is the official way to interact with the B-Bot Platform. It provides a type-safe interface to manage Distribution Channels (Assistants), Threads, and Runs, built on top of the LangGraph SDK but adapted for B-Bot’s terminology.
Installation
npm install @beyond-bot-ai/sdk
Quick Start
Initialize the client with your B-Bot API Key. The SDK is pre-configured to connect to the B-Bot API.
import { BBotClient } from "@beyond-bot-ai/sdk";
const client = new BBotClient({
apiKey: "bbot_your_api_key_here" // Your B-Bot API Key
});
Getting Your API Key
- Go to B-Bot Hub
- Navigate to Settings → API Keys
- Click Create New API Key
- Copy the key (starts with
bbot_)
- Store it securely (treat it like a password!)
Never commit your API key to version control. Use environment variables:const client = new BBotClient({
apiKey: process.env.BBOT_API_KEY
});
Core Concepts
1. Distribution Channels
In B-Bot, AI Assistants are exposed as Distribution Channels. You can search, retrieve, and manage them using the client.distributionChannels property.
// Search for available channels
const channels = await client.distributionChannels.search({
limit: 10,
offset: 0
});
// Get a specific channel by assistant_id
const channel = await client.distributionChannels.get("assistant-id");
// Extract entity_id from channel config (required for runs)
const entityId = channel.config?.configurable?.entity_id;
2. Threads
Threads persist the state of a conversation. Every interaction happens within a thread.
// Create a new thread
const thread = await client.threads.create();
// Add initial messages to the thread state
await client.threads.updateState(thread.thread_id, {
values: {
messages: [
{ role: "user", content: "Hello, B-Bot!" }
]
}
});
3. Streaming Runs (Recommended)
Important: B-Bot sends cumulative content in messages/partial events (e.g., “Hello”, “Hello!”, “Hello! How”), not individual tokens. Your onMessage callback should replace the content, not append it.
The SDK includes a powerful Streaming Handler (client.streamRun) that simplifies processing real-time events like token streaming, tool execution, and state updates.
// Get the channel first to extract entity_id
const channel = await client.distributionChannels.get("assistant-id");
const entityId = channel.config?.configurable?.entity_id;
// Stream a run (this waits until the stream completes)
await client.streamRun(
"thread-id",
channel.assistant_id, // Use assistant_id from the channel
{
messages: [
{ role: "user", content: "Write a short poem about AI." }
]
},
{
// Handle real-time token streaming
// isCumulative=true means REPLACE content, don't append
onMessage: (content, isCumulative) => {
if (isCumulative) {
// Replace the entire message content
setStreamingContent(content);
} else {
// Append (rare case)
setStreamingContent(prev => prev + content);
}
},
// Handle tool execution events
onToolEvent: (event) => {
console.log("\n[Tool Running]:", event.tool_name);
},
// Handle completion
onUpdate: (messages) => {
console.log("\n[Done]");
},
onError: (err) => console.error("Error:", err)
},
{ entity_id: entityId } // Pass entity_id from channel config
);
Manual Streaming (Advanced)
If you need lower-level control over the stream:
const stream = await client.runs.stream(
threadId,
assistantId, // Note: Use assistant_id, not channel_id
{
input: {
messages: [
{ role: "user", content: "Help me with marketing." }
],
entity_id: entityId // Required by B-Bot graph
},
streamMode: ["values", "messages"]
}
);
// This blocks until the stream completes
for await (const chunk of stream) {
console.log(chunk.event, chunk.data);
}
State Management (Todos & Files)
The SDK automatically extracts structured data like Todos and Files generated by the AI.
await client.streamRun(
threadId,
assistantId,
{ messages: [...] },
{
// Called when the AI creates or updates todos
onTodosUpdate: (todos) => {
console.log("Active Todos:", todos);
},
// Called when the AI generates files
onFilesUpdate: (files) => {
// files is a map of { filename: content }
for (const [name, content] of Object.entries(files)) {
saveFile(name, content);
}
}
},
{ entity_id: entityId }
);
Debugging
If onMessage is not being called or you’re not receiving events, enable debug mode:
await client.streamRun(
threadId,
assistantId,
{ messages: [...] },
{
onMessage: (content, isCumulative) => {
console.log("Received:", content);
}
},
{
entity_id: entityId,
debug: true // Enable detailed logging
}
);
This will log:
- Every chunk received from the stream
- Event types and data structures
- Content extraction process
- Total chunks processed
Common Pitfalls
1. Missing entity_id
B-Bot requires entity_id in the initial state. Always extract it from the channel config:
const channel = await client.distributionChannels.get(assistantId);
const entityId = channel.config?.configurable?.entity_id;
2. Using channel_id instead of assistant_id
The API returns assistant_id, not channel_id. Use channel.assistant_id.
3. Appending cumulative content
B-Bot sends the full message so far in each chunk. Always replace content when isCumulative=true.
Features
- Native Terminology: Uses
client.distributionChannels instead of client.assistants.
- Streaming Handler: Built-in
streamRun helper for easy real-time UI updates.
- State Extraction: Automatically extracts Todos and Files from stream events.
- Auto-Configuration: Pre-configured for
api.b-bot.space.
- Type Safety: Full TypeScript support.
- Cumulative Streaming: Properly handles B-Bot’s cumulative content streaming.
License
MIT