Constructor
const context = new ExuluContext(options: ExuluContextOptions);
Creates a new ExuluContext instance. See the configuration guide for all available options.
Item management methods
createItem()
Creates a new item in the context. Optionally triggers processor and embeddings generation.
async createItem(
item: Item,
config: ExuluConfig,
user?: number,
role?: string,
upsert?: boolean,
generateEmbeddingsOverwrite?: boolean
): Promise<{ item: Item; job?: string }>
Item data matching the context’s field schema
ExuluApp configuration object
User ID for access control and tracking
Role ID for access control
If true, update existing item if id or external_id matches (default: false)
generateEmbeddingsOverwrite
Override the calculateVectors configuration for this operation
The created item with generated id
Comma-separated job IDs if processor or embeddings were queued
const { item, job } = await context.createItem(
{
external_id: "doc-123",
name: "Getting Started",
content: "Welcome to our platform...",
category: "guide"
},
config,
userId
);
console.log(`Created item ${item.id}`);
if (job) {
console.log(`Queued jobs: ${job}`);
}
When upsert: true, the item is created if it doesn’t exist, or updated if an item with the same external_id or id exists.
updateItem()
Updates an existing item. Optionally triggers processor and embeddings generation.
async updateItem(
item: Item,
config: ExuluConfig,
user?: number,
role?: string,
generateEmbeddingsOverwrite?: boolean
): Promise<{ item: Item; job?: string }>
Item data with id field and fields to update
ExuluApp configuration object
User ID for access control and tracking
Role ID for access control
generateEmbeddingsOverwrite
Override the calculateVectors configuration
Comma-separated job IDs if processor or embeddings were queued
const { item } = await context.updateItem(
{
id: "123e4567-e89b-12d3-a456-426614174000",
content: "Updated content...",
category: "reference"
},
config,
userId
);
deleteItem()
Deletes an item and its associated chunks.
async deleteItem(
item: Item,
user?: number,
role?: string
): Promise<{ id: string; job?: string }>
Item with id or external_id to delete
Role ID for access control
await context.deleteItem({
id: "123e4567-e89b-12d3-a456-426614174000"
});
This permanently deletes the item and all its embedding chunks. This operation cannot be undone.
getItem()
Retrieves a single item by ID or external ID.
async getItem({ item }: { item: Item }): Promise<Item>
Object with id or external_id field
The item with all fields and chunksCount property
const item = await context.getItem({
item: { id: "123e4567-e89b-12d3-a456-426614174000" }
});
// Or by external_id
const item = await context.getItem({
item: { external_id: "doc-123" }
});
console.log(`Item has ${item.chunksCount} chunks`);
This method does not apply access control. You are responsible for implementing access control in your application.
getItems()
Retrieves multiple items with optional filters.
async getItems({
filters,
fields
}: {
filters?: any[];
fields?: string[];
}): Promise<Item[]>
Array of filter conditions (field, operator, value)
Array of field names to return (default: all fields)
Array of items matching the filters
const items = await context.getItems({
filters: [
{ field: "category", operator: "=", value: "guide" },
{ field: "archived", operator: "=", value: false }
],
fields: ["id", "name", "category"]
});
deleteAll()
Deletes all items and chunks from the context.
async deleteAll(): Promise<{
count: number;
results: any;
errors?: string[];
}>
await context.deleteAll();
This is a destructive operation that deletes all data in the context. Use with extreme caution.
Search methods
search()
Performs semantic, keyword, or hybrid search on the context.
async search(options: SearchOptions): Promise<SearchResult>
Natural language search query
Specific keywords to search for
Search method: "cosineDistance", "tsvector", or "hybridSearch"
Filters to apply to items table
Filters to apply to chunks table
User object for access control
Maximum number of results to return
Page number for pagination (1-indexed)
options.trigger
STATISTICS_LABELS
required
Trigger source for tracking: "agent", "api", "processor", etc.
Override default cutoff scores
Override default chunk expansion
chunks
VectorSearchChunkResult[]
Array of matching chunks with metadata
Context metadata (name, id, embedder)
const results = await context.search({
query: "How do I configure authentication?",
keywords: ["auth", "config"],
method: "hybridSearch",
itemFilters: [
{ field: "category", operator: "=", value: "guide" }
],
chunkFilters: [],
user: currentUser,
limit: 10,
page: 1,
sort: undefined,
trigger: "api"
});
results.chunks.forEach(chunk => {
console.log(chunk.chunk_content);
console.log(chunk.item_name);
console.log(chunk.chunk_metadata);
});
Hybrid search
Semantic search
Keyword search
Combines semantic and keyword search. Best for most queries. Pure vector similarity search. Best for conceptual queries. Full-text keyword search. Best for exact terms and IDs.
Embeddings methods
embeddings.generate.one()
Generates embeddings for a single item.
async embeddings.generate.one({
item,
user,
role,
trigger,
config
}: EmbeddingsGenerateOneOptions): Promise<{
id: string;
job?: string;
chunks?: number;
}>
Item to generate embeddings for (must have id)
trigger
STATISTICS_LABELS
required
Trigger source: "agent", "api", "processor", etc.
Job ID if queued for background processing
Number of chunks generated (if not queued)
const { id, job, chunks } = await context.embeddings.generate.one({
item: { id: "123e4567-e89b-12d3-a456-426614174000" },
user: userId,
trigger: "api",
config: config
});
if (job) {
console.log(`Embeddings queued as job ${job}`);
} else {
console.log(`Generated ${chunks} chunks`);
}
embeddings.generate.all()
Generates embeddings for all items in the context.
async embeddings.generate.all(
config: ExuluConfig,
userId?: number,
roleId?: string,
limit?: number
): Promise<{
jobs: string[];
items: number;
}>
Maximum number of items to process
Array of job IDs if queued
Number of items processed
const { jobs, items } = await context.embeddings.generate.all(
config,
userId,
undefined,
1000 // Process first 1000 items
);
console.log(`Processing ${items} items in ${jobs.length} jobs`);
Without a queue configured, this method can only process up to 2,000 items. For larger datasets, configure the embedder with a queue.
Processor methods
processField()
Processes an item using the configured processor.
async processField(
trigger: STATISTICS_LABELS,
item: Item,
exuluConfig: ExuluConfig,
user?: number,
role?: string
): Promise<{
result: Item | undefined;
job?: string;
}>
trigger
STATISTICS_LABELS
required
Trigger source for tracking
Processed item (undefined if queued or filtered out)
Job ID if queued for background processing
const { result, job } = await context.processField(
"api",
item,
config,
userId
);
if (job) {
console.log(`Processing queued as job ${job}`);
} else {
console.log("Processed result:", result);
}
This method is typically called automatically by createItem() and updateItem() when a processor is configured.
Source methods
executeSource()
Executes a data source to fetch and return items.
async executeSource(
source: ExuluContextSource,
inputs: any,
exuluConfig: ExuluConfig
): Promise<Item[]>
source
ExuluContextSource
required
Source configuration to execute
Input parameters for the source
Array of items fetched from the source
const source = context.sources[0];
const items = await context.executeSource(
source,
{ since: "2024-01-01" },
config
);
console.log(`Fetched ${items.length} items from ${source.name}`);
Table management methods
createItemsTable()
Creates the database table for storing items.
async createItemsTable(): Promise<void>
await context.createItemsTable();
This is typically called automatically by db.init() when initializing the database. You rarely need to call it manually.
createChunksTable()
Creates the database table for storing embedding chunks.
async createChunksTable(): Promise<void>
await context.createChunksTable();
This method requires an embedder to be configured, as it uses the embedder’s vector dimensions to create the table schema.
tableExists()
Checks if the items table exists in the database.
async tableExists(): Promise<boolean>
const exists = await context.tableExists();
if (!exists) {
await context.createItemsTable();
}
chunksTableExists()
Checks if the chunks table exists in the database.
async chunksTableExists(): Promise<boolean>
const exists = await context.chunksTableExists();
Exports the context as a tool that agents can use.
Tool instance or null if enableAsTool: false
const tool = context.tool();
if (tool) {
console.log(tool.name); // "{context_name}_context_search"
console.log(tool.description);
}
This method is called automatically by ExuluApp when registering contexts. The generated tool is added to the tools registry.
Internal methods
createAndUpsertEmbeddings()
Internal method that generates embeddings and upserts chunks into the database.
async createAndUpsertEmbeddings(
item: Item,
config: ExuluConfig,
user?: number,
statistics?: ExuluStatisticParams,
role?: string,
job?: string
): Promise<{
id: string;
chunks?: number;
job?: string;
}>
This is an internal method. Use embeddings.generate.one() instead.
Properties
Unique context identifier
console.log(context.id); // "product_docs"
Human-readable context name
console.log(context.name); // "Product Documentation"
description
Whether the context is active
fields
ExuluContextFieldDefinition[]
Array of field definitions
context.fields.forEach(field => {
console.log(`${field.name}: ${field.type}`);
});
embedder
embedder
ExuluEmbedder | undefined
Configured embedder instance
processor
processor
ExuluContextProcessor | undefined
Configured processor
sources
configuration
Context configuration object
console.log(context.configuration.maxRetrievalResults);
console.log(context.configuration.calculateVectors);
Usage examples
Complete CRUD workflow
// Create
const { item } = await context.createItem(
{
name: "Getting Started Guide",
content: "This guide helps you...",
category: "guide"
},
config,
userId
);
// Read
const retrieved = await context.getItem({ item: { id: item.id } });
// Update
await context.updateItem(
{
id: item.id,
content: "Updated content..."
},
config,
userId
);
// Search
const results = await context.search({
query: "getting started",
method: "hybridSearch",
itemFilters: [],
chunkFilters: [],
limit: 10,
page: 1,
sort: undefined,
trigger: "api"
});
// Delete
await context.deleteItem({ id: item.id });
Bulk embeddings generation
// Generate embeddings for specific items
const items = await context.getItems({
filters: [
{ field: "embeddings_updated_at", operator: "IS", value: null }
]
});
for (const item of items) {
await context.embeddings.generate.one({
item,
trigger: "api",
config
});
}
// Or generate for all items
await context.embeddings.generate.all(config);
Custom search with filters
const results = await context.search({
query: "authentication configuration",
keywords: ["oauth", "jwt"],
method: "hybridSearch",
itemFilters: [
{ field: "category", operator: "=", value: "guide" },
{ field: "archived", operator: "=", value: false }
],
chunkFilters: [],
user: currentUser,
role: currentUser.role.id,
limit: 20,
page: 1,
sort: undefined,
trigger: "api",
cutoffs: {
hybrid: 0.7 // Higher relevance threshold
},
expand: {
before: 2,
after: 2 // More context
}
});