LibreChat/api/server/controllers/agents/queuedTurns.js
Danny Avila c7f0a8f247
📬 feat: Move Agent Queued Turns Server-Side (#15370)
* feat: move agent queued turns server-side

* test: update queued turn composition coverage

* fix: harden queued-turn lifecycle ownership

* fix: centralize queued-turn lifecycle ownership

* fix: close queued-turn lifecycle gaps

* fix: unify queued turn lifecycle transitions

* fix: fence queued-turn deletion admission

* fix: preserve queued-turn lifecycle ownership

* fix: close queued-turn reconciliation races

* fix: reconcile quarantined queued-turn admissions

* fix: annotate admission evidence default

* fix: deepen queued turn lifecycle admission

* fix: fence queued turn provider admission
2026-08-30 21:53:58 -04:00

80 lines
2.3 KiB
JavaScript

const {
handleAgentQueuedTurnEnqueue,
handleAgentQueuedTurnList,
handleAgentQueuedTurnCancel,
} = require('@librechat/api');
const { logger } = require('@librechat/data-schemas');
const db = require('~/models');
const { createAgentAccessCheck } = require('./steer');
const dependencies = (req) => {
/** Keep trigger-service composition lazy so importing the route for unrelated
* middleware probes does not initialize or require the worker graph. */
const {
scheduleAgentQueuedTurn,
cancelAgentQueuedTurn,
} = require('~/server/services/Agents/triggers');
return {
methods: db,
lifecycle: {
schedule: scheduleAgentQueuedTurn,
cancel: cancelAgentQueuedTurn,
},
getFiles: db.getFiles,
updateFilesUsage: db.updateFilesUsage,
checkAgentAccess: createAgentAccessCheck(req),
isPrincipalActive: db.isAgentTriggerPrincipalActive,
};
};
const send = (res, result) => res.status(result.status).json(result.body);
const AgentQueuedTurnEnqueueController = async (req, res) => {
try {
return send(
res,
await handleAgentQueuedTurnEnqueue(req.user ?? {}, req.body ?? {}, dependencies(req)),
);
} catch (error) {
logger.error('[AgentQueuedTurns] Failed to enqueue turn', error);
return res.status(500).json({ code: 'QUEUED_TURN_FAILED' });
}
};
const AgentQueuedTurnListController = async (req, res) => {
try {
return send(
res,
await handleAgentQueuedTurnList(
req.user ?? {},
req.query?.conversationId,
dependencies(req),
req.query?.clientRequestIds,
),
);
} catch (error) {
logger.error('[AgentQueuedTurns] Failed to list turns', error);
return res.status(500).json({ code: 'QUEUED_TURN_LIST_FAILED' });
}
};
const AgentQueuedTurnCancelController = async (req, res) => {
try {
return send(
res,
await handleAgentQueuedTurnCancel(
req.user ?? {},
req.params?.queuedTurnId,
dependencies(req),
),
);
} catch (error) {
logger.error('[AgentQueuedTurns] Failed to cancel turn', error);
return res.status(500).json({ code: 'QUEUED_TURN_CANCEL_FAILED' });
}
};
module.exports = {
AgentQueuedTurnEnqueueController,
AgentQueuedTurnListController,
AgentQueuedTurnCancelController,
};