Skip to main content
The ExuluContext constructor takes a single options object. This page documents every option, verified against the current @exulu/backend source.

Identity

string
required
Unique identifier. Lowercased with spaces replaced by underscores, it becomes the Postgres table prefix: <id>_items, <id>_chunks, and (with the entity layer) <id>_entities. Must start with a letter or underscore, contain only letters, digits, and underscores, and be at most 80 characters — treat 5 as the practical minimum.
string
required
Human-readable name shown in the platform UI and logs.
string
required
What this context contains. Surfaced to users and agents choosing where to search.
boolean
required
Whether the context is active and available.
Never change id after the context has data — the tables are named after it, so a renamed context points at new, empty tables.

Fields

ExuluContextFieldDefinition[]
required
The custom schema for items, on top of the built-in columns (id, name, description, tags, archived, external_id, created_by, ttl, rights_mode, embeddings_updated_at, last_processed_at, textlength, source, chunks_count, createdAt, updatedAt).
string
required
Column name. Sanitized to lowercase with underscores. For file fields, the actual column is <name>_s3key.
ExuluFieldTypes
required
One of text, longText, shortText, number, boolean, code, json, enum, markdown, file, date, uuid. See the type table below for the Postgres column each maps to.
boolean
Whether the field can be edited in the platform UI after creation.
boolean
Adds a unique constraint on the column.
boolean
Whether a value is required when creating items through the platform API.
any
Default value declared for the field. Surfaced through the context’s table definition (API and admin UI); the Postgres column itself is created without a database-level default.
boolean
Marks the field as computed (for example, filled by a processor) rather than user-provided.
boolean
Whether to index the field for faster filtering.
string[]
For enum fields: the allowed values.
allFileTypes[]
For file fields: the accepted file types (for example ["pdf", "docx"]).
boolean
Marks the field as a write-only secret. Hidden fields are excluded from the generated GraphQL object type (unreadable via any query or mutation response), the generated Filter input type (prevents boolean/timing oracle attacks on secret values), the SQL SELECT list, and all read payloads. They are also excluded from groupBy and sort — the allow-list checked before any user-supplied column name reaches SQL rejects hidden field names. Writes via the mutation Input type are still accepted, so the mutation layer can hash and store passwords, API keys, and tokens. Use hidden: true for any column that must never appear in read responses.

Field type reference

Embedder

ExuluContextEmbedder
A reference to a LiteLLM embedding model, plus an optional queue. Without an embedder, vector and hybrid search are unavailable — the context still works for structured storage and full-text search.
string
required
The model_name of an embedding model declared in config.litellm.yaml. The model’s model_info must declare its dimensionality — the chunks table’s vector(n) column is sized from it, and table creation throws if it is missing.
Promise<ExuluQueueConfig>
When set, embedding generation is scheduled as a BullMQ job on this queue instead of running inline. Required in practice for bulk generation: without a queue, embeddings.generate.all() refuses to process more than 2,000 items.
ExuluQueues.register(name, concurrency, ratelimit?, timeoutInSeconds?) registers a BullMQ queue and returns { use }; calling .use() yields the Promise<ExuluQueueConfig> the embedder, processor, and sources expect. Registering queues requires an Enterprise Edition license.

Chunker

ChunkerOperation
default:"defaultChunker"
Splits an item into embeddable chunks before the embedder runs. When omitted, the built-in defaultChunker (a sentence chunker) runs over the item’s content field — falling back to description — combined with name. Contexts with structured or file-backed content should supply their own.
maxChunkSize is the per-chunk token budget, derived from the embedding model. utils.storage gives file-backed chunkers access to object storage. Chunk metadata lands in the chunks table’s JSONB column, so any JSON-serializable value (for example a page number) is allowed.
@exulu/backend also exports ready-made chunkers under ExuluChunkers (sentence, markdown, recursive) and the defaultChunker itself.

Sources

ExuluContextSource[]
required
Data sources that ingest items from external systems. Pass an empty array if the context has none.
string
required
Unique source ID — also used as the BullMQ job scheduler key.
string
required
Human-readable name.
string
required
What the source ingests.
string
Cron expression, for example "0 */6 * * *" for every six hours. When the worker process starts (app.bullmq.workers.create()), it upserts a BullMQ job scheduler per source that has both a schedule and a queue. Sources without a queue log a warning and are skipped.
Promise<ExuluQueueConfig>
The queue the source job runs on.
number
default:"3"
BullMQ retry attempts for a failed run.
object
default:"{ type: \"exponential\", delay: 2000 }"
Retry backoff strategy.
object[]
Declared input parameters (name, description, optional default) for manual runs — surfaced in the platform UI when triggering the source by hand. Values arrive in execute’s inputs.
function
required
Async function that fetches external data and returns an array of items (ExuluItem). Each returned item is written with createItem: items carrying an external_id (or id) are upserted — existing rows with the same external_id are updated — while items without one are inserted fresh. Processor and embedding triggers apply as configured.

Processor

ExuluContextProcessor
Transforms items after they are written — extract text from an uploaded file, enrich a record, compute derived fields. The result is written back to the items table and can trigger embedding generation.
string
required
Processor name, used in job labels.
string
required
What the processor does.
function
Optional predicate. Return a falsy value to skip processing for an item — for example, when no file is attached yet.
function
required
The transformation. Receives the item and utils.storage for reading files from object storage; must return the updated item, which is persisted with last_processed_at set.
string
required
When the processor runs: manual (only explicit processField() calls), or automatically on writes. Both createItem() and updateItem() run the processor when the trigger is onInsert, onUpdate, or always — currently the three non-manual values behave identically on both write paths.
Promise<ExuluQueueConfig>
Run processing as a background job instead of inline.
number
default:"600"
Job timeout in queue mode.
boolean
When true, embedding generation is triggered automatically after the processor finishes.

Retrieval hooks

(query: string) => Promise<string>
Rewrites the natural-language query before retrieval — for example, expanding it with an LLM. Applied inside the search pipeline whenever a query is present.
(results: chunk[]) => Promise<chunk[]>
Declared hook for reordering retrieved chunks after search. Each chunk carries chunk_content, chunk_index, chunk_id, chunk_source, chunk_metadata, chunk_created_at, chunk_updated_at, item_id, item_external_id, and item_name.
resultReranker is accepted and stored on the context, but the current search pipeline does not invoke it — the call site is disabled in the source. Don’t rely on it running until a release notes otherwise.

Retrieval configuration

object
Retrieval and write behavior. When you omit the entire object, the defaults below apply. When you pass a partial object, only your keys are set — the per-key defaults are not merged in, so pass everything you rely on.
"manual" | "onUpdate" | "onInsert" | "always"
default:"manual"
When embeddings are generated automatically: never (manual), when items are created (onInsert), updated (onUpdate), or both (always). With manual, call embeddings.generate.one() / .all() yourself or pass the generateEmbeddingsOverwrite flag on writes.
number
default:"10"
Fallback result limit used when a search() call passes no limit.
"private" | "users" | "roles" | "teams" | "public"
default:"private"
Default rights_mode for new items — the items table column defaults to this value.
object
Minimum relevance scores per search method. Results scoring below the cutoff are dropped. Can be overridden per search() call.
object
default:"{ before: 0, after: 0 }"
Number of neighboring chunks to include around each matched chunk, giving agents more surrounding context. Can be overridden per search() call.
("german" | "english")[]
default:"[\"english\"]"
Languages for the generated full-text search columns. Each language adds a to_tsvector expression to the items and chunks tables, affecting stemming and stop words. Set before the tables are created — the columns are generated at table-creation time.

Entity layer

ExuluEntitiesConfig
Opt-in entity extraction over chunks. When present (or when an admin has configured entity types for the context in the UI), IMP extracts typed entities from embedded content into <id>_entities, enabling entity filters and insights in search(). Absent → behavior is unchanged.
object[]
Entity types declared in code, for example { name: "Person", description: "A natural person mentioned in the document." }. Merged (union) with types an admin declares in the UI.
string
Model ID used for extraction. Falls back to a platform default when omitted.
number
default:"0.3"
Weight of the shared-entity boost term in retrieval ranking.
number
default:"0.5"
Mentions below this extractor confidence are dropped.
string
default:"english"
Target language for canonical entity names.
See Entities for the admin-side view of the entity layer.

Complete example

Next steps

API reference

Search, item CRUD, embeddings, entity layer, and table methods.

ExuluApp

Register the context on the app.