Constructor
const app = new ExuluApp();
Creates a new ExuluApp instance. The constructor takes no parameters. You must call create() to initialize the app.
Methods
create()
Initializes the ExuluApp with all components and returns the initialized instance.
async create(options: CreateOptions): Promise<ExuluApp>
options.contexts
Record<string, ExuluContext>
Object mapping context IDs to ExuluContext instances
Configuration object for the app
Array of custom agents to register in addition to default agents
Array of custom tools to register in addition to default tools
Array of custom evaluations to register in addition to default evaluations
Array of reranker instances for improving search results
Returns the initialized ExuluApp instance
const app = new ExuluApp();
await app.create({
contexts: {
docs: myDocsContext
},
config: {
workers: { enabled: true },
MCP: { enabled: false },
telemetry: { enabled: false }
},
agents: [myCustomAgent],
tools: [myCustomTool]
});
All context, agent, tool, and reranker IDs must be valid PostgreSQL identifiers: start with a letter or underscore, contain only letters, digits, or underscores, be 5-80 characters long.
express.init()
Initializes and returns the Express application with all routes configured.
async express.init(): Promise<Express>
Returns the Express app instance ready to listen on a port
const expressApp = await app.express.init();
expressApp.listen(3000, () => {
console.log("Server running on port 3000");
});
This method must be called before accessing app.expressApp. It configures all GraphQL and REST routes, initializes logging, and optionally starts the MCP server.
Retrieves a registered tool by its ID.
tool(id: string): ExuluTool | undefined
The unique identifier of the tool
Returns the tool if found, otherwise undefined
const perplexityTool = app.tool("perplexity_search");
if (perplexityTool) {
console.log(perplexityTool.name);
}
Returns all registered tools including default tools, custom tools, and context-generated tools.
Array of all registered tools
const allTools = app.tools();
console.log(`Registered ${allTools.length} tools`);
context()
Retrieves a registered context by its ID.
context(id: string): ExuluContext | undefined
The unique identifier of the context
Returns the context if found, otherwise undefined
const docsContext = app.context("documentation");
if (docsContext) {
console.log(docsContext.name);
}
agent()
Retrieves a registered agent by its ID.
agent(id: string): ExuluAgent | undefined
The unique identifier of the agent
Returns the agent if found, otherwise undefined
const claudeAgent = app.agent("claude_sonnet_45");
if (claudeAgent) {
console.log(claudeAgent.name);
}
embeddings.generate.one()
Generates embeddings for a single item in a context.
async embeddings.generate.one(options: GenerateOneOptions): Promise<any>
The item ID within the context
Returns the embedding generation result
await app.embeddings.generate.one({
context: "documentation",
item: "doc_123"
});
This method retrieves the item from the database, generates its embeddings using the context’s configured embedder, and stores them in the vector database.
embeddings.generate.all()
Generates embeddings for all items in a context.
async embeddings.generate.all(options: GenerateAllOptions): Promise<any>
Returns the embedding generation result for all items
await app.embeddings.generate.all({
context: "documentation"
});
This method processes all items in the context and can be resource-intensive for large datasets. Consider using background workers for production workloads.
bullmq.workers.create()
Creates and starts BullMQ workers for processing background jobs.
async bullmq.workers.create(queues?: string[]): Promise<any>
Optional array of queue names to listen to. If not provided, workers listen to all registered queues.
// Start workers for all queues
await app.bullmq.workers.create();
// Start workers for specific queues only
await app.bullmq.workers.create(["embeddings", "agent_requests"]);
Workers automatically set up schedulers for context sources with configured schedules. This enables periodic data synchronization.
Properties
expressApp
Returns the initialized Express application instance.
public get expressApp(): Express
const app = await exuluApp.express.init();
const server = exuluApp.expressApp.listen(3000);
Throws an error if express.init() has not been called yet.
contexts
Returns all registered contexts as an array.
public get contexts(): ExuluContext[]
Array of all registered contexts
const contexts = app.contexts;
console.log(`Registered ${contexts.length} contexts`);
Returns all registered agents including default and custom agents.
public get agents(): ExuluAgent[]
Array of all registered agents
const agents = app.agents;
agents.forEach(agent => {
console.log(`${agent.name} (${agent.id})`);
});
TypeScript types
ExuluConfig
type ExuluConfig = {
telemetry?: {
enabled: boolean;
};
logger?: {
winston: {
transports: winston.transport[];
};
};
workers: {
enabled: boolean;
logger?: {
winston: {
transports: winston.transport[];
};
};
telemetry?: {
enabled: boolean;
};
};
MCP: {
enabled: boolean;
};
fileUploads?: {
s3region: string;
s3key: string;
s3secret: string;
s3Bucket: string;
s3endpoint?: string;
s3prefix?: string;
};
privacy?: {
systemPromptPersonalization?: boolean;
};
};
CreateOptions
type CreateOptions = {
contexts?: Record<string, ExuluContext>;
config: ExuluConfig;
agents?: ExuluAgent[];
tools?: ExuluTool[];
evals?: ExuluEval[];
rerankers?: ExuluReranker[];
};
Usage examples
Basic server setup
import { ExuluApp } from "@exulu/backend";
const app = new ExuluApp();
await app.create({
config: {
workers: { enabled: false },
MCP: { enabled: false },
telemetry: { enabled: false }
}
});
const expressApp = await app.express.init();
expressApp.listen(3000);
Server with workers
// server.ts
import { ExuluApp } from "@exulu/backend";
const app = new ExuluApp();
await app.create({
config: {
workers: { enabled: true },
MCP: { enabled: true },
telemetry: { enabled: true }
}
});
const expressApp = await app.express.init();
expressApp.listen(3000);
// workers.ts (separate process)
import { app } from "./server";
await app.bullmq.workers.create();
With custom components
import {
ExuluApp,
ExuluContext,
ExuluAgent,
ExuluTool
} from "@exulu/backend";
const customContext = new ExuluContext({
id: "my_context",
name: "My Context",
// ... context configuration
});
const customAgent = new ExuluAgent({
id: "my_agent",
name: "My Agent",
// ... agent configuration
});
const customTool = new ExuluTool({
id: "my_tool",
name: "My Tool",
// ... tool configuration
});
const app = new ExuluApp();
await app.create({
contexts: {
my_context: customContext
},
agents: [customAgent],
tools: [customTool],
config: {
workers: { enabled: true },
MCP: { enabled: false },
telemetry: { enabled: false }
}
});
Accessing registered components
// Get specific components
const agent = app.agent("claude_sonnet_45");
const context = app.context("documentation");
const tool = app.tool("perplexity_search");
// List all components
console.log("Agents:", app.agents.map(a => a.name));
console.log("Contexts:", app.contexts.map(c => c.name));
console.log("Tools:", app.tools().map(t => t.name));
// Generate embeddings
await app.embeddings.generate.all({ context: "documentation" });