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

Constructor

See Configuration for the full options object.

search()

Runs vector, full-text, or hybrid retrieval over the context’s chunks, with RBAC filtering, score cutoffs, and chunk expansion.
options.query
string
Natural-language query. Embedded via the context’s embedding model for cosineDistance and hybridSearch. If a queryRewriter is configured, it runs first.
options.keywords
string[]
Keywords for full-text matching (tsvector and hybridSearch).
options.itemFilters
SearchFilters
required
Filters on item columns. SearchFilters is an array of objects mapping field names to operators: eq, ne, in, contains, and, or — plus lte/gte for numbers and dates. Pass [] for none.
options.chunkFilters
SearchFilters
required
Filters on chunk columns, same operator shape. Pass [] for none.
options.user
User
When set, access control is applied — only chunks from items the user may read (by rights_mode, ownership, role, or team) are returned.
options.role
string
Role ID used alongside user for access control.
options.method
VectorMethod
required
"cosineDistance" (vector similarity), "tsvector" (full-text), or "hybridSearch" (both combined).
options.sort
any
required
Sort configuration; pass undefined for relevance ordering.
options.trigger
STATISTICS_LABELS
required
Where the search originated, recorded in usage statistics — for example "api" or "agent".
options.limit
number
required
Maximum results. When falsy, falls back to configuration.maxRetrievalResults (default 10).
options.page
number
required
Page number for pagination.
options.cutoffs
object
Per-call override of the configured score cutoffs.
options.expand
object
Per-call override of the configured chunk expansion window.
options.entityFilter
EntityFilter
Entity-layer filter: { entityIds?: string[]; entities?: { type: string; name: string }[]; mode?: "any" | "all" }. With "any" (default) a chunk must mention at least one of the entities; with "all", all of them. Requires the entity layer.
options.queryEmbedding
number[]
Precomputed query embedding — skips re-embedding the query. Must come from this context’s embedding model.
chunks
VectorSearchChunkResult[]
Matched chunks. Each carries chunk_content, chunk_index, chunk_id, chunk_source, chunk_metadata, timestamps, item_id, item_external_id, item_name, item timestamps, the method-specific scores (chunk_cosine_distance, chunk_fts_rank, chunk_hybrid_score), and — with the entity layer on — chunk_entities.
context
object
{ name, id, embedder } of the searched context.
entityInsights
EntityInsights
Present when the entity layer is on: entities recognized in the query, how often they matched, and their top co-occurring entities.

Item management

createItem()

Inserts (or upserts) an item, then runs the processor and embedding generation as configured.
item
Item
required
Item data matching the context’s schema. json field values that are objects or arrays are stringified automatically; tags arrays are joined to a comma-separated string.
config
ExuluConfig
required
The app’s ExuluConfig — needed for storage access in processors and chunkers.
user
number
User ID for tracking and access control.
role
string
Role ID for tracking and access control.
upsert
boolean
default:"false"
When true, requires external_id or id on the item and merges on conflict — external_id takes precedence. Throws when neither is present.
generateEmbeddingsOverwrite
boolean
Per-call override of configuration.calculateVectors: true forces embedding generation, false suppresses it.
item
Item
An object containing only the generated id — re-fetch with getItem() if you need the full row.
job
string
Comma-separated job IDs when the processor and/or embedder ran in queue mode.
Embeddings are generated when the context has an embedder, generateEmbeddingsOverwrite is not false, and either the override is true or calculateVectors is onInsert / always. The processor runs when its trigger is onInsert, onUpdate, or always.

updateItem()

Updates an existing item by id, then runs the processor and embedding generation as configured.
item
Item
required
Must include id plus the fields to update. Throws when no row matches.
config
ExuluConfig
required
The app’s ExuluConfig.
user
number
User ID for tracking.
role
string
Role ID for tracking.
generateEmbeddingsOverwrite
boolean
true forces embedding generation, false suppresses it; otherwise calculateVectors of onUpdate / always applies.
runProcessorOverwrite
boolean
true forces the processor to run, false suppresses it; otherwise any non-manual trigger applies.
item
Item
The item as it was before the update — the method returns the previously fetched record, not the merged result.
job
string
Comma-separated job IDs when the processor and/or embedder ran in queue mode.

deleteItem()

Deletes an item and its chunks. Accepts either id or external_id.
item
Item
required
Object with id or external_id. When only external_id is given, the row is resolved first; throws when not found.
id
string
ID of the deleted item.
Permanently deletes the item and all of its embedding chunks. There is no undo.

getItem()

Fetches a single item by id or external_id, with its chunk count.
item
Item
required
Object with id or external_id.
return
Promise<Item>
The item with all columns plus a chunksCount property.
getItem() applies no access control — it is intended for internal use. Enforce permissions yourself, or pass a user to getItems().

getItems()

Fetches items with optional filters, field selection, and access control.
filters
any[]
Filter array in the same operator shape as search() filters, for example [{ category: { eq: "guide" } }].
fields
string[]
Columns to return. Defaults to all.
user
User
When set, access control is applied and only rows the user may read are returned. When omitted, no access control is applied.
role
string
Role ID folded into the access-control check alongside user.

deleteAll()

Deletes every item, every chunk, and — when the entity layer is on — every entity in the context.
Destroys all data in the context. The returned count and results are currently placeholder values (0 and []) — don’t build logic on them.

Embeddings

embeddings.generate.one()

Generates embeddings for one item: loads the full record, chunks it, embeds the chunks through LiteLLM, and replaces the item’s rows in the chunks table. When the embedder has a queue, the work is scheduled as a job instead.
options.item
Item
required
Must contain id. The full record is re-fetched from the database, so partial items are safe.
options.trigger
STATISTICS_LABELS
required
Statistics label, for example "api" or "processor".
options.config
ExuluConfig
required
The app’s ExuluConfig.
id
string
The item ID.
job
string
Job ID when the embedder runs in queue mode (chunks is 0 in that case).
chunks
number
Number of chunks written when run inline.
Throws when the context has no embedder or the item has no id.

embeddings.generate.all()

Generates (or queues) embeddings for all items in the context, one generate.one() call per item.
config
ExuluConfig
required
The app’s ExuluConfig.
userId
number
User ID for tracking.
roleId
string
Role ID for tracking.
limit
number
Cap on the number of items to process.
jobs
string[]
Job IDs (queue mode).
items
number
Number of items processed.
Without a queue on the embedder, this throws when the context holds more than 2,000 items — configure embedder.queue for bulk generation.

createAndUpsertEmbeddings()

Low-level worker used by embeddings.generate.one(): chunks, embeds, deletes the item’s old chunks, inserts the new ones, updates chunks_count and embeddings_updated_at, and re-runs entity extraction when the entity layer is on.
Internal — prefer embeddings.generate.one(), which handles queue mode and record hydration for you. Worker processes call this directly when executing embedding jobs.

Processing

processField()

Runs the configured processor on an item — either inline or, when the processor has a queue, as a background job. On inline success the result is written back to the items table with last_processed_at set, and embeddings are triggered when processor.config.generateEmbeddings is true.
trigger
STATISTICS_LABELS
required
Statistics label for the run.
item
Item
required
The item to process.
exuluConfig
ExuluConfig
required
The app’s ExuluConfig — provides storage access to the processor’s utils.storage.
result
Item | undefined
The processed item, or undefined when the job was queued or the processor’s filter skipped the item.
job
string
Job ID in queue mode, or the follow-up embeddings job ID when generateEmbeddings queued one.
Throws when the context has no processor. Normally you don’t call this yourself — createItem() and updateItem() invoke it based on the processor’s trigger.

Sources

executeSource()

Runs a source’s execute function with the given inputs and returns the fetched items. It does not write them — the worker’s scheduled source jobs handle persistence, upserting returned items that carry an external_id (or id) and inserting the rest.
source
ExuluContextSource
required
One of the context’s sources.
inputs
any
required
Input values, spread into the source’s execute arguments alongside exuluConfig.
return
Promise<Item[]>
The items the source produced.

Entity layer

Available under context.entityLayer when the entity layer is enabled. See Entities for the admin UI these methods power.

entityLayer.countStale()

Counts items whose entities were extracted with an out-of-date entity-type set — used for the admin “run backfill?” prompt.
Returns 0 when the entity layer is disabled. When the signature column doesn’t exist yet, every item counts as stale.

entityLayer.backfill()

Re-extracts entities across existing items, inline and in batches.
options.onlyStale
boolean
default:"true"
Limit the run to items whose entity-type signature is out of date.
options.limit
number
default:"5000"
Cap per run; items beyond it are reported in skipped and left for the next run.
This re-runs entity extraction only — it does not re-embed items.

entityLayer.extractItem()

Extracts and ingests entities for a single item. Powers the item detail page’s extraction test action.
Throws when the entity layer is not configured (no entity types, or no embedder).

entityLayer.detachItem()

Removes all entity links from one item and prunes entities that end up orphaned.

entityLayer.purgeType()

Deletes all entities of a given type; their chunk mentions cascade away.

Table management

These are called by ExuluDatabase.init() / platform database initialization — you rarely invoke them yourself.

createItemsTable()

Creates <id>_items with the built-in columns, your custom fields, the generated fts tsvector column (per configured language), and a GIN index on it.

createChunksTable()

Creates <id>_chunks with content, JSONB metadata, chunk_index, a pgvector embedding column sized from the embedding model’s declared dimensionality, a generated fts column, a GIN index, and an HNSW cosine index.
Requires an embedder — the vector dimensionality comes from the model’s model_info in config.litellm.yaml, and this throws when the model isn’t declared or lacks a dimensionality.

tableExists()

Whether <id>_items exists.

chunksTableExists()

Whether <id>_chunks exists.

Properties

All constructor options are exposed as public properties:

Complete workflow