⚙️ perf: reduce first-load MongoDB round trips (#14101)

* perf(api): reduce first-load database round trips

* docs: move agent guidance to claude docs

* refactor(api): move message validation into api package

* fix(api): narrow active generation job lookup

* fix(api): preserve omitted source identity
This commit is contained in:
Ravi Kumar L 2026-07-06 15:36:34 +02:00 committed by GitHub
parent a0aa1f2b9d
commit 44d1275f36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 895 additions and 242 deletions

View file

@ -3,9 +3,12 @@ jest.mock('~/models', () => ({
}));
jest.mock('@librechat/api', () => ({
createMessageRequestMiddleware:
jest.requireActual('@librechat/api').createMessageRequestMiddleware,
GenerationJobManager: {
getJob: jest.fn(),
},
isPendingActionStale: jest.fn(() => false),
}));
jest.mock('@librechat/data-schemas', () => ({

View file

@ -1,5 +1,5 @@
const { logger } = require('@librechat/data-schemas');
const { isEmailDomainAllowed } = require('@librechat/api');
const { getAppConfigOptionsFromUser, isEmailDomainAllowed } = require('@librechat/api');
const { getAppConfig } = require('~/server/services/Config');
/**
@ -16,11 +16,7 @@ const { getAppConfig } = require('~/server/services/Config');
const checkDomainAllowed = async (req, res, next) => {
try {
const email = req?.user?.email;
const appConfig = await getAppConfig({
role: req?.user?.role,
userId: req?.user?.id,
tenantId: req?.user?.tenantId,
});
const appConfig = await getAppConfig(getAppConfigOptionsFromUser(req?.user));
if (email && !isEmailDomainAllowed(email, appConfig?.registration?.allowedDomains)) {
logger.error(`[Social Login] [Social Login not allowed] [Email: ${email}]`);

View file

@ -1,12 +1,10 @@
const { logger } = require('@librechat/data-schemas');
const { getAppConfigOptionsFromUser } = require('@librechat/api');
const { getAppConfig } = require('~/server/services/Config');
const configMiddleware = async (req, res, next) => {
try {
const userRole = req.user?.role;
const userId = req.user?.id;
const tenantId = req.user?.tenantId;
req.config = await getAppConfig({ role: userRole, userId, tenantId });
req.config = await getAppConfig(getAppConfigOptionsFromUser(req.user));
next();
} catch (error) {

View file

@ -3,6 +3,7 @@ const setTwoFactorTempUser = require('./setTwoFactorTempUser');
const validateRegistration = require('./validateRegistration');
const buildEndpointOption = require('./buildEndpointOption');
const validateMessageReq = require('./validateMessageReq');
const { prepareMessageRequestValidation, sendValidationResponse } = require('./messageValidation');
const checkDomainAllowed = require('./checkDomainAllowed');
const requireLocalAuth = require('./requireLocalAuth');
const canDeleteAccount = require('./canDeleteAccount');
@ -47,6 +48,8 @@ module.exports = {
configMiddleware,
checkDomainAllowed,
validateMessageReq,
sendValidationResponse,
prepareMessageRequestValidation,
buildEndpointOption,
validateRegistration,
validatePasswordReset,

View file

@ -0,0 +1,14 @@
const {
GenerationJobManager,
createMessageRequestMiddleware,
isPendingActionStale,
} = require('@librechat/api');
const { logger } = require('@librechat/data-schemas');
const { getConvo } = require('~/models');
module.exports = createMessageRequestMiddleware({
getConvo,
getJob: (conversationId) => GenerationJobManager.getJob(conversationId),
isPendingActionStale,
logger,
});

View file

@ -1,78 +1,3 @@
const { GenerationJobManager, isPendingActionStale } = require('@librechat/api');
const { logger } = require('@librechat/data-schemas');
const { getConvo } = require('~/models');
function hasTenantMismatch(job, user) {
// Untenanted jobs remain readable by their owner for pre-multi-tenancy deployments.
return job.metadata?.tenantId != null && job.metadata.tenantId !== user.tenantId;
}
async function canReadActiveJobConversation(req, conversationId) {
if (req.method !== 'GET' || req.params?.messageId) {
return false;
}
let job;
try {
job = await GenerationJobManager.getJob(conversationId);
} catch (error) {
logger.warn(`[validateMessageReq] Active job lookup failed for ${conversationId}:`, error);
return false;
}
// A job paused for human review is still active (consistent with /chat/status
// and /chat/active), so a new-conversation run that pauses before its final
// save can still recover the prompt — but only while it has a live,
// resolvable prompt (missing/malformed or past-expiry reads as inactive).
const isActive =
!!job &&
(job.status === 'running' ||
(job.status === 'requires_action' &&
!isPendingActionStale({ pendingAction: job.metadata?.pendingAction })));
if (!isActive) {
return false;
}
return job.metadata?.userId === req.user.id && !hasTenantMismatch(job, req.user);
}
// Middleware to validate conversationId and user relationship
const validateMessageReq = async (req, res, next) => {
const body = req.body ?? {};
const paramConversationId = req.params?.conversationId;
const bodyConversationId = body.conversationId;
const nestedConversationId = body.message?.conversationId;
if (
(paramConversationId &&
((bodyConversationId && paramConversationId !== bodyConversationId) ||
(nestedConversationId && paramConversationId !== nestedConversationId))) ||
(bodyConversationId && nestedConversationId && bodyConversationId !== nestedConversationId)
) {
return res.status(400).json({ error: 'Conversation ID mismatch' });
}
const conversationId = paramConversationId || bodyConversationId || nestedConversationId;
if (conversationId === 'new') {
return res.status(200).send([]);
}
const conversation = await getConvo(req.user.id, conversationId);
if (!conversation) {
if (await canReadActiveJobConversation(req, conversationId)) {
return next();
}
return res.status(404).json({ error: 'Conversation not found' });
}
if (conversation.user !== req.user.id) {
return res.status(403).json({ error: 'User not authorized for this conversation' });
}
next();
};
const { validateMessageReq } = require('./messageValidation');
module.exports = validateMessageReq;