Skip to main content
All signatures on this page are verified against the current @exulu/backend source. For constructor-time options, see Configuration.

Constructor

Takes no parameters. The instance does nothing until you call create().

Lifecycle

create()

Initializes the app: merges built-in contexts, registers default providers, tools, and evals, validates IDs, checks the queue license, and probes system dependencies. See Introduction for the full behavior list.
options.config
ExuluConfig
required
Platform configuration. See Configuration.
options.contexts
Record<string, ExuluContext>
Contexts to register. Built-in contexts win on key collision.
options.agents
ExuluAgent[]
Code-defined agents, merged with database agents at read time.
options.providers
ExuluProvider[]
Custom providers, appended after the 19 defaults.
options.evals
ExuluEval[]
Custom evals. Only registered when Redis is configured.
options.tools
ExuluTool[]
Custom tools, registered ahead of the built-in tools.
return
Promise<ExuluApp>
The initialized instance (the same object you called create() on). It is also stored in an internal singleton.
create() throws on invalid IDs, on registered queues without an Enterprise Edition license, and — unless requireSystemDependencies is false — on missing system dependencies.

express.init()

Builds and returns the Express application: registers the GraphQL and REST routes, sets up authentication middleware and logging, mounts the MCP endpoints when config.MCP.enabled is true, starts the LiteLLM proxy supervisor when EXULU_USE_LITELLM=true, and starts the transcription polling loop when TRANSCRIPTION_SERVER is set.
return
Promise<Express>
The Express application, ready to listen() on a port. Calling express.init() again returns the same instance.
If the LiteLLM supervisor fails to start, express.init() does not throw — the app keeps booting so the admin UI stays reachable, and agent requests fail with LITELLM_NOT_READY until the underlying issue is fixed and the process restarted.

expressApp

Getter for the initialized Express application.
return
Express
The Express application created by express.init().
Throws if express.init() has not been called yet.

Component accessors

tool()

Returns a registered tool by ID.
id
string
required
The tool ID.
return
ExuluTool | undefined
The tool, or undefined if no tool with that ID is registered.

tools()

Returns all registered tools: your custom tools plus the built-ins.
return
ExuluTool[]
All registered tools.

context()

Returns a registered context by ID.
id
string
required
The context ID.
return
ExuluContext | undefined
The context, or undefined if not registered.

contexts

Getter returning all registered contexts (yours plus built-ins) as an array.

provider()

Returns a registered model provider by ID.
id
string
required
The provider ID.
return
ExuluProvider | undefined
The provider, or undefined if not registered.

providers

Getter returning all registered providers — the 19 defaults plus any you passed to create().

agent()

Resolves an agent by ID. Unlike the other accessors, this is async: agents can be defined in code (passed to create()) or created in the database through the platform UI, and this method checks both.
id
string
required
The agent ID.
include
object
default:"{ source: { code: true, database: true } }"
Which sources to check. Code-defined agents are checked first; database agents second.
return
Promise<ExuluAgent | undefined>
The agent with its RBAC block resolved. Code-defined agents without an explicit RBAC get a default public one and source: "code".
When the database source is included and no agent matches in either source, this method throws Agent instance not found. rather than returning undefined. It only returns undefined when the database lookup is excluded (include.source.database: false) and no code-defined agent matches.

agents()

Returns all agents. Also async — database agents are fetched and their RBAC resolved; code-defined agents are prepended with default public RBAC.
include
object
default:"{ source: { code: true, database: true } }"
Which sources to include.
return
Promise<ExuluAgent[]>
Code-defined agents first, then database agents.

Embeddings

App-level convenience wrappers around the per-context embedding methods. They resolve the context by ID and delegate to the context’s own embeddings methods.

embeddings.generate.one()

Loads one item from the context’s items table by ID and generates (or queues) its embeddings.
options.context
string
required
The context ID.
options.item
string
required
The item ID (UUID) within that context.
id
string
The item ID.
job
string
Job ID when the context’s embedder runs on a queue.
chunks
number
Number of chunks written when embeddings were generated inline.
Throws if the context ID is not registered.

embeddings.generate.all()

Generates (or queues) embeddings for every item in a context.
options.context
string
required
The context ID.
jobs
string[]
Job IDs when the embedder runs on a queue.
items
number
Number of items processed.
Without a queue configured on the context’s embedder, this throws when the context holds more than 2,000 items. Configure embedder.queue for larger datasets.

Workers

bullmq.workers.create()

Starts BullMQ workers in the current process. Run this in a dedicated worker process, not inside the HTTP server.
queues
string[]
Queue names this worker should listen to. When omitted, the worker listens to all registered queues.
return
Promise<Worker[]>
The BullMQ Worker instances, one per queue.
What it does before starting the workers:
  1. Checks the license — throws without a valid EXULU_ENTERPRISE_LICENSE covering queues.
  2. Enables LiteLLM client mode — when EXULU_USE_LITELLM=true, the worker health-probes the server-managed proxy instead of spawning its own.
  3. Configures worker logging — uses workers.logger.winston.transports, falling back to logger.winston.transports, then to the built-in console transport.
  4. Creates context source schedulers — for every context source with a config.schedule cron expression and a queue, a BullMQ job scheduler is upserted with the source’s retries (default 3) and backoff (default exponential, 2000 ms).
Throws if create() has not resolved yet — always await the create() promise before starting workers.

Types

ExuluConfig

Documented in full in Configuration.

Create options

Putting it together