Documentation organized with equilibrium: - Small (50-100 lines): Index files - Medium (250-400 lines): Guides - Large (450-600 lines): Complete references Structure: - docs/api/ - REST endpoints, WebSocket - docs/guides/ - Getting started, deployment, templates - docs/reference/ - BASIC language, configuration, architecture Updated README.md to point to new docs location.
6.3 KiB
6.3 KiB
WebSocket API
Real-time bidirectional communication with General Bots.
Connection
Endpoint
ws://localhost:8080/ws
wss://your-domain.com/ws (production)
Authentication
Include the auth token as a query parameter or in the first message:
// Option 1: Query parameter
const ws = new WebSocket('ws://localhost:8080/ws?token=<auth_token>');
// Option 2: First message
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'auth',
token: '<auth_token>'
}));
};
Message Format
All messages are JSON objects with a type field:
{
"type": "message_type",
"payload": { ... },
"timestamp": "2024-01-01T10:00:00Z"
}
Client Messages
Send Chat Message
{
"type": "message",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"content": "Hello, I need help with my order"
}
Start Typing
{
"type": "typing_start",
"session_id": "550e8400-e29b-41d4-a716-446655440000"
}
Stop Typing
{
"type": "typing_stop",
"session_id": "550e8400-e29b-41d4-a716-446655440000"
}
Subscribe to Session
{
"type": "subscribe",
"session_id": "550e8400-e29b-41d4-a716-446655440000"
}
Unsubscribe from Session
{
"type": "unsubscribe",
"session_id": "550e8400-e29b-41d4-a716-446655440000"
}
Ping (Keep-Alive)
{
"type": "ping"
}
Server Messages
Chat Response
{
"type": "message",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "msg-uuid",
"role": "assistant",
"content": "I'd be happy to help! What's your order number?",
"timestamp": "2024-01-01T10:00:01Z"
}
Streaming Response
For LLM responses, content streams in chunks:
{
"type": "stream_start",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "msg-uuid"
}
{
"type": "stream_chunk",
"message_id": "msg-uuid",
"content": "I'd be happy to "
}
{
"type": "stream_chunk",
"message_id": "msg-uuid",
"content": "help! What's your "
}
{
"type": "stream_end",
"message_id": "msg-uuid",
"content": "I'd be happy to help! What's your order number?"
}
Bot Typing Indicator
{
"type": "bot_typing",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"is_typing": true
}
Tool Execution
When the bot calls a tool:
{
"type": "tool_call",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"tool": "search_orders",
"arguments": {"order_id": "12345"}
}
{
"type": "tool_result",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"tool": "search_orders",
"result": {"status": "shipped", "tracking": "1Z999..."}
}
Error
{
"type": "error",
"code": "SESSION_NOT_FOUND",
"message": "Session does not exist or has expired"
}
Pong (Keep-Alive Response)
{
"type": "pong",
"timestamp": "2024-01-01T10:00:00Z"
}
Session Events
{
"type": "session_created",
"session_id": "550e8400-e29b-41d4-a716-446655440000"
}
{
"type": "session_closed",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"reason": "user_disconnect"
}
JavaScript Client Example
class BotClient {
constructor(url, token) {
this.url = url;
this.token = token;
this.ws = null;
this.handlers = {};
}
connect() {
this.ws = new WebSocket(`${this.url}?token=${this.token}`);
this.ws.onopen = () => {
console.log('Connected to bot');
this.emit('connected');
};
this.ws.onmessage = (event) => {
const data = JSON.parse(event.data);
this.emit(data.type, data);
};
this.ws.onclose = () => {
console.log('Disconnected');
this.emit('disconnected');
// Auto-reconnect after 3 seconds
setTimeout(() => this.connect(), 3000);
};
this.ws.onerror = (error) => {
console.error('WebSocket error:', error);
this.emit('error', error);
};
}
send(type, payload) {
if (this.ws?.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({ type, ...payload }));
}
}
sendMessage(sessionId, content) {
this.send('message', { session_id: sessionId, content });
}
subscribe(sessionId) {
this.send('subscribe', { session_id: sessionId });
}
on(event, handler) {
this.handlers[event] = this.handlers[event] || [];
this.handlers[event].push(handler);
}
emit(event, data) {
(this.handlers[event] || []).forEach(h => h(data));
}
disconnect() {
this.ws?.close();
}
}
// Usage
const client = new BotClient('ws://localhost:8080/ws', 'auth-token');
client.on('connected', () => {
client.subscribe('session-uuid');
});
client.on('message', (data) => {
console.log('Bot:', data.content);
});
client.on('stream_chunk', (data) => {
process.stdout.write(data.content);
});
client.on('error', (data) => {
console.error('Error:', data.message);
});
client.connect();
client.sendMessage('session-uuid', 'Hello!');
Meet WebSocket
Video conferencing uses a separate WebSocket endpoint:
ws://localhost:8080/ws/meet
Join Room
{
"type": "join",
"room_id": "room-uuid",
"participant_name": "John"
}
Leave Room
{
"type": "leave",
"room_id": "room-uuid"
}
Signaling (WebRTC)
{
"type": "signal",
"room_id": "room-uuid",
"target_id": "participant-uuid",
"signal": { /* WebRTC signal data */ }
}
Connection Limits
| Limit | Value |
|---|---|
| Max connections per IP | 100 |
| Max message size | 64 KB |
| Idle timeout | 5 minutes |
| Ping interval | 30 seconds |
Error Codes
| Code | Description |
|---|---|
AUTH_FAILED |
Invalid or expired token |
SESSION_NOT_FOUND |
Session doesn't exist |
RATE_LIMITED |
Too many messages |
MESSAGE_TOO_LARGE |
Exceeds 64 KB limit |
INVALID_FORMAT |
Malformed JSON |
SUBSCRIPTION_FAILED |
Cannot subscribe to session |