🧹 chore: Optimize provisioning — single credential load, deferred DB writes

- loadCodeApiKey: load CODE_API_KEY once per request, pass to both
  checkSessionsAlive and provisionToCodeEnv (was N+1 lookups)
- provisionToCodeEnv/provisionToVectorDB now return fileUpdate objects
  instead of writing to DB immediately
- primeResources batches all DB updates via Promise.allSettled after
  provisioning completes
- Remove updateFile import from provision.js (no longer writes directly)
This commit is contained in:
Danny Avila 2026-03-22 12:54:26 -04:00
parent 40b3bc9b84
commit ebbcd9c674
4 changed files with 109 additions and 48 deletions

View file

@ -32,10 +32,12 @@ import { generateArtifactsPrompt } from '~/prompts';
import { getProviderConfig } from '~/endpoints';
import { primeResources } from './resources';
import type {
TFileUpdate,
TFilterFilesByAgentAccess,
TProvisionToCodeEnv,
TProvisionToVectorDB,
TCheckSessionsAlive,
TLoadCodeApiKey,
} from './resources';
/**
@ -156,6 +158,10 @@ export interface InitializeAgentDbMethods extends EndpointDbMethods {
provisionToVectorDB?: TProvisionToVectorDB;
/** Optional: batch-check code env file liveness */
checkSessionsAlive?: TCheckSessionsAlive;
/** Optional: load CODE_API_KEY once per request */
loadCodeApiKey?: TLoadCodeApiKey;
/** Optional: persist file metadata updates after provisioning */
updateFile?: (data: TFileUpdate) => Promise<unknown>;
}
/**
@ -316,6 +322,8 @@ export async function initializeAgent(
provisionToCodeEnv: db.provisionToCodeEnv,
provisionToVectorDB: db.provisionToVectorDB,
checkSessionsAlive: db.checkSessionsAlive,
loadCodeApiKey: db.loadCodeApiKey,
updateFile: db.updateFile as ((data: TFileUpdate) => Promise<unknown>) | undefined,
});
const {

View file

@ -5,25 +5,34 @@ import type { IMongoFile, AppConfig, IUser } from '@librechat/data-schemas';
import type { FilterQuery, QueryOptions, ProjectionType } from 'mongoose';
import type { Request as ServerRequest } from 'express';
/** Deferred DB update from provisioning (batched after all files are provisioned) */
export type TFileUpdate = {
file_id: string;
metadata?: Record<string, unknown>;
embedded?: boolean;
};
/**
* Function type for provisioning a file to the code execution environment.
* @returns The fileIdentifier from the code env
* @returns The fileIdentifier and a deferred DB update object
*/
export type TProvisionToCodeEnv = (params: {
req: ServerRequest & { user?: IUser };
file: TFile;
entity_id?: string;
}) => Promise<string>;
apiKey?: string;
}) => Promise<{ fileIdentifier: string; fileUpdate: TFileUpdate }>;
/**
* Function type for provisioning a file to the vector DB for file_search.
* @returns Object with embedded status
* @returns Object with embedded status and a deferred DB update object
*/
export type TProvisionToVectorDB = (params: {
req: ServerRequest & { user?: IUser };
file: TFile;
entity_id?: string;
}) => Promise<{ embedded: boolean }>;
existingStream?: unknown;
}) => Promise<{ embedded: boolean; fileUpdate: TFileUpdate | null }>;
/**
* Function type for batch-checking code env file liveness.
@ -32,10 +41,13 @@ export type TProvisionToVectorDB = (params: {
*/
export type TCheckSessionsAlive = (params: {
files: TFile[];
userId: string;
apiKey: string;
staleSafeWindowMs?: number;
}) => Promise<Set<string>>;
/** Loads CODE_API_KEY for a user. Call once per request. */
export type TLoadCodeApiKey = (userId: string) => Promise<string>;
/**
* Function type for retrieving files from the database
* @param filter - MongoDB filter query for files
@ -197,6 +209,8 @@ export const primeResources = async ({
provisionToCodeEnv,
provisionToVectorDB,
checkSessionsAlive,
loadCodeApiKey,
updateFile,
}: {
req: ServerRequest & { user?: IUser };
appConfig?: AppConfig;
@ -214,6 +228,10 @@ export const primeResources = async ({
provisionToVectorDB?: TProvisionToVectorDB;
/** Optional callback to batch-check code env file liveness by session */
checkSessionsAlive?: TCheckSessionsAlive;
/** Optional callback to load CODE_API_KEY once per request */
loadCodeApiKey?: TLoadCodeApiKey;
/** Optional callback to persist file metadata updates after provisioning */
updateFile?: (data: TFileUpdate) => Promise<unknown>;
}): Promise<{
attachments: Array<TFile | undefined>;
tool_resources: AgentToolResources | undefined;
@ -366,20 +384,34 @@ export const primeResources = async ({
enabledToolResources.has(EToolResources.file_search) && provisionToVectorDB != null;
if (needsCodeEnv || needsVectorDB) {
// Load CODE_API_KEY once for all code env operations
let codeApiKey: string | undefined;
if (needsCodeEnv && loadCodeApiKey && req.user?.id) {
try {
codeApiKey = await loadCodeApiKey(req.user.id);
} catch (error) {
logger.error('[primeResources] Failed to load CODE_API_KEY', error);
warnings.push('Code execution file provisioning unavailable');
}
}
// Batch staleness check: verify code env files are still alive
let aliveFileIds: Set<string> = new Set();
if (needsCodeEnv && checkSessionsAlive && req.user?.id) {
if (needsCodeEnv && codeApiKey && checkSessionsAlive) {
const filesWithIdentifiers = attachments.filter(
(f) => f?.metadata?.fileIdentifier && f.file_id,
);
if (filesWithIdentifiers.length > 0) {
aliveFileIds = await checkSessionsAlive({
files: filesWithIdentifiers as TFile[],
userId: req.user.id,
apiKey: codeApiKey,
});
}
}
// Collect deferred DB updates from provisioning
const pendingUpdates: TFileUpdate[] = [];
// Provision files in parallel
const provisionResults = await Promise.allSettled(
attachments.map(async (file) => {
@ -393,6 +425,7 @@ export const primeResources = async ({
// Code env provisioning (with staleness check)
if (
needsCodeEnv &&
codeApiKey &&
!processedResourceFiles.has(`${EToolResources.execute_code}:${file.file_id}`)
) {
const hasFileIdentifier = !!file.metadata?.fileIdentifier;
@ -408,12 +441,14 @@ export const primeResources = async ({
}
try {
const fileIdentifier = await provisionToCodeEnv({
const { fileIdentifier, fileUpdate } = await provisionToCodeEnv({
req: typedReq,
file,
entity_id: agentId,
apiKey: codeApiKey,
});
file.metadata = { ...file.metadata, fileIdentifier };
pendingUpdates.push(fileUpdate);
addFileToResource({
file,
resourceType: EToolResources.execute_code,
@ -451,6 +486,9 @@ export const primeResources = async ({
});
if (result.embedded) {
file.embedded = true;
if (result.fileUpdate) {
pendingUpdates.push(result.fileUpdate);
}
addFileToResource({
file,
resourceType: EToolResources.file_search,
@ -473,6 +511,11 @@ export const primeResources = async ({
logger.error('[primeResources] Unexpected provisioning rejection', result.reason);
}
}
// Batch DB updates after all provisioning completes
if (pendingUpdates.length > 0 && updateFile) {
await Promise.allSettled(pendingUpdates.map((update) => updateFile(update)));
}
}
}