Skip to main content
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.

NPM Package

View on NPM

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

  1. Go to B-Bot Hub
  2. Navigate to SettingsAPI Keys
  3. Click Create New API Key
  4. Copy the key (starts with bbot_)
  5. 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!" }
    ]
  }
});
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