Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lumia Orchestrator

A master orchestration server for coordinating multiple LumiaBot instances, enabling coordinated responses, bantering systems, and cross-guild bot management.

Features

  • Bot Coordination: Orchestrate response timing between all connected LumiaBot "nodes"
  • Response Ordering: Set up response order and feed necessary context across all bots
  • Bantering System: Create interactive "bantering" between multiple bots
  • Safety Caps: Hard cap response turns to prevent runaway bot responses
  • Cross-Guild Detection: Detect when mentioned bots don't share a guild and allow independent responses
  • Shared Knowledge Layer: Load markdown/frontmatter docs directly into the orchestrator for collective lookups
  • Vector Retrieval: Optional LanceDB-backed semantic search with HNSW-PQ indexing and OpenAI-compatible embeddings
  • Real-time Communication: WebSocket-based communication for low-latency coordination
  • REST API: HTTP endpoints for management and monitoring

Architecture

┌─────────────────────────────────────────────────────────────┐
│                    Lumia Orchestrator                        │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │   REST API   │  │ WebSocket    │  │   Services   │      │
│  │   Routes     │  │   Manager    │  │              │      │
│  └──────────────┘  └──────────────┘  └──────────────┘      │
│         │                │                    │               │
│         ▼                ▼                    ▼               │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              Response Coordinator                    │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────┐ │   │
│  │  │ Turn Manager │  │ Banter System│  │  Safety  │ │   │
│  │  └──────────────┘  └──────────────┘  └──────────┘ │   │
│  └─────────────────────────────────────────────────────┘   │
│                              │                              │
│                              ▼                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                  Bot Registry                        │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────┐ │   │
│  │  │  Bot Nodes   │  │   Guilds     │  │  Health  │ │   │
│  │  └──────────────┘  └──────────────┘  └──────────┘ │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
                              │
                              │ WebSocket / REST
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    LumiaBot Instances                        │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │   LumiaBot   │  │   LumiaBot   │  │   LumiaBot   │      │
│  │   Node 1     │  │   Node 2     │  │   Node N     │      │
│  └──────────────┘  └──────────────┘  └──────────────┘      │
└─────────────────────────────────────────────────────────────┘

Installation

# Clone the repository
git clone <repository-url>
cd lumia-orchestrator

# Install dependencies
bun install

# Copy environment file
cp .env.example .env

# Edit .env with your configuration

Configuration

Create a .env file with the following variables:

# Server Configuration
PORT=3000
HOST=0.0.0.0
NODE_ENV=production

# Security
API_KEY=your-super-secret-api-key-min-16-chars
COUNCIL_FAMILY_NAME=Lumias
JWT_SECRET=your-jwt-secret

# Orchestrator Knowledge Graph
KNOWLEDGE_GRAPH_ENABLED=true
KNOWLEDGE_GRAPH_DIR=./knowledge_documents
KNOWLEDGE_GRAPH_TOP_K=8
KNOWLEDGE_ONLY_INCLUDE_OVER=0.2

# Optional LanceDB vector search
KNOWLEDGE_VECTOR_ENABLED=false
KNOWLEDGE_VECTOR_DB_DIR=./data/lancedb
KNOWLEDGE_VECTOR_EMBEDDING_BASE_URL=https://api.openai.com/v1
KNOWLEDGE_VECTOR_EMBEDDING_API_KEY=your-embedding-api-key
KNOWLEDGE_VECTOR_EMBEDDING_MODEL=text-embedding-3-large
KNOWLEDGE_VECTOR_EMBEDDING_BATCH_SIZE=20

# Bot Coordination Settings
MAX_RESPONSE_TURNS=5
RESPONSE_TIMEOUT_MS=30000
BANTER_COOLDOWN_MS=5000

# WebSocket Settings
WS_HEARTBEAT_INTERVAL_MS=30000
WS_MAX_CONNECTIONS=100

# Logging
LOG_LEVEL=info
LOG_FORMAT=json

# Feature Flags
ENABLE_BANTER_SYSTEM=true
ENABLE_RESPONSE_CAP=true
ENABLE_CROSS_GUILD_DETECTION=true

Running the Server

# Development mode with hot reload
bun run dev

# Production mode
bun run start

Orchestrator Knowledge Documents

The orchestrator can load its own shared markdown knowledge corpus from KNOWLEDGE_GRAPH_DIR. These files use the same frontmatter format as the bot-side knowledge_documents/ folder.

Example:

---
topic: frontmatter
title: Shared Frontmatter Notes
keywords: frontmatter, metadata, markdown
type: document
priority: 8
---

Shared orchestrator knowledge goes here.

This is useful when you want one central source of truth for KNOWLEDGE_GRAPH_SOURCE_MODE=1 or a second shared layer for KNOWLEDGE_GRAPH_SOURCE_MODE=2.

Converting MkDocs-style docs

If you have Zensical or MkDocs-style docs, place them in knowledge_documents/to_convert/ and run:

bun run convert-knowledge-docs

This writes converted frontmatter docs into knowledge_documents/converted/. The converter uses the document title plus its parent category path to generate frontmatter metadata and normalizes common MkDocs constructs like admonitions and tab blocks. By default it wipes the output directory first so stale converted docs do not linger. Pass --no-clean if you want to preserve existing output.

Files inside knowledge_documents/to_convert/ are ignored by the orchestrator loader, so only the converted output is embedded and indexed at startup.

If KNOWLEDGE_VECTOR_ENABLED=true, the orchestrator will also:

  • chunk each document for retrieval,
  • prepend title/topic/keywords into each chunk for stronger semantic relevance,
  • embed chunks through your configured OpenAI-compatible endpoint,
  • store them in LanceDB,
  • build an HNSW-PQ vector index plus a full-text index,
  • run hybrid retrieval for better QA-style lookups.

Scoring notes:

  • LanceDB vector search is distance-based, so lower cosine distance is better.
  • LanceDB FTS search is BM25-based, so higher relevance is better.
  • The orchestrator normalizes those signals into a shared 0-1 relevance score, blends them with metadata weighting, and filters out low-confidence hits using KNOWLEDGE_ONLY_INCLUDE_OVER.

API Endpoints

Bot Management

  • GET /api/v1/bots - List all registered bots
  • GET /api/v1/bots/:botId - Get bot details

Guild Management

  • GET /api/v1/guilds - List all guilds
  • GET /api/v1/guilds/:guildId/bots - List bots in a guild

Mention Handling

  • POST /api/v1/mention - Submit a mention event for coordination

Turn Management

  • GET /api/v1/turns/:turnId - Get turn details
  • POST /api/v1/turns/:turnId/complete - Mark turn as complete

Session Management

  • GET /api/v1/sessions - List active banter sessions
  • POST /api/v1/sessions/:sessionId/end - End a session

Monitoring

  • GET /health - Health check endpoint
  • GET /api/v1/stats - Server statistics

WebSocket Protocol

Client → Server Messages

Register

{
  "type": "register",
  "payload": {
    "botId": "bot-123",
    "name": "LumiaBot-Alpha",
    "token": "discord-token",
    "guilds": ["guild-1", "guild-2"],
    "metadata": {}
  }
}

Heartbeat

{
  "type": "heartbeat",
  "payload": {
    "botId": "bot-123",
    "timestamp": "2024-01-01T00:00:00Z",
    "guilds": ["guild-1", "guild-2"],
    "status": "online"
  }
}

Mention

{
  "type": "mention",
  "payload": {
    "eventId": "event-123",
    "messageId": "msg-456",
    "channelId": "channel-789",
    "guildId": "guild-abc",
    "authorId": "user-xyz",
    "authorName": "UserName",
    "content": "@LumiaBot-Alpha @LumiaBot-Beta hello!",
    "mentionedBotIds": ["bot-123", "bot-456"],
    "timestamp": "2024-01-01T00:00:00Z"
  }
}

Response Complete

{
  "type": "response_complete",
  "payload": {
    "turnId": "turn-123",
    "botId": "bot-123",
    "responseContent": "Hello there! How can I help?"
  }
}

Server → Client Messages

Register Acknowledgment

{
  "type": "register_ack",
  "payload": {
    "success": true,
    "botId": "bot-123",
    "registeredAt": "2024-01-01T00:00:00Z"
  }
}

Response Request

{
  "type": "response_request",
  "payload": {
    "turnId": "turn-123",
    "eventId": "event-456",
    "botId": "bot-123",
    "context": {
      "previousMessages": [...],
      "conversationId": "conv-789",
      "turnCount": 0,
      "maxTurns": 5,
      "isBanter": false
    },
    "timeoutAt": "2024-01-01T00:00:30Z"
  }
}

Banter Invite

{
  "type": "banter_invite",
  "payload": {
    "sessionId": "session-123",
    "inviterBotId": "bot-456",
    "inviteeBotIds": ["bot-123"],
    "channelId": "channel-789",
    "guildId": "guild-abc",
    "topic": "general chat"
  }
}

Error

{
  "type": "error",
  "payload": {
    "code": "TURN_NOT_FOUND",
    "message": "Turn not found",
    "details": {}
  }
}

Integration with LumiaBot

To integrate the orchestrator with your LumiaBot instances:

import { LumiaBotIntegration } from 'lumia-orchestrator';

const orchestrator = new LumiaBotIntegration({
  orchestratorUrl: 'ws://localhost:3000',
  apiKey: 'your-api-key',
  botId: 'my-bot-id',
  botName: 'MyLumiaBot',
  token: 'discord-bot-token',
  guilds: ['guild-id-1', 'guild-id-2'],
});

// Set up response handler
orchestrator.setResponseHandler(async (context) => {
  // Your bot's response logic here
  // Access context.previousMessages for conversation history
  return "Hello! I'm responding in turn.";
});

// Connect to orchestrator
await orchestrator.connect();

// When your bot receives a mention, notify the orchestrator
await orchestrator.notifyMention({
  eventId: 'unique-event-id',
  messageId: 'discord-message-id',
  channelId: 'channel-id',
  guildId: 'guild-id',
  authorId: 'user-id',
  authorName: 'UserName',
  content: 'Message content with @mentions',
  mentionedBotIds: ['bot-id-1', 'bot-id-2'],
  timestamp: new Date(),
});

// Update guilds when bot joins/leaves guilds
orchestrator.updateGuilds(['new-guild-id-1', 'new-guild-id-2']);

// Disconnect when shutting down
orchestrator.disconnect();

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages