Files
chat/api/server/middleware/limiters/cloudAgentLimiter.js
zeekay 32969de598 fork: rename internal workspace packages to @hanzochat scope
librechat-data-provider  → @hanzochat/data-provider
@librechat/data-schemas  → @hanzochat/data-schemas
@librechat/client        → @hanzochat/client
(@hanzochat/api already forked; external @librechat/agents fork follows)

All imports, package.json names/deps, tsconfig path aliases, jest
moduleNameMapper, and rollup/vite build aliases updated. The data-provider
react-query subpath resolves via the exports map. Lockfiles regenerated in a
follow-on once the canonical package manager is confirmed.
2026-07-14 05:55:49 -07:00

45 lines
1.4 KiB
JavaScript

const rateLimit = require('express-rate-limit');
const { limiterCache } = require('@hanzochat/api');
const { ViolationTypes } = require('@hanzochat/data-provider');
const logViolation = require('~/cache/logViolation');
/**
* Per-user rate limiter for the cloud-agents proxy (`/v1/chat/agents/cloud/*`). A run
* is a real, billable cloud chat completion that holds an upstream socket for up
* to 30s, yet it bypasses the message limiters that guard the sibling completion
* path. This caps a signed-in user to CLOUD_AGENT_USER_MAX requests per window so
* a loop cannot degrade the shared backend or run up denial-of-wallet cost.
* Keyed by user id (the route is JWT-only; guests never reach it).
*/
const {
CLOUD_AGENT_USER_MAX = 30,
CLOUD_AGENT_WINDOW = 1,
CLOUD_AGENT_VIOLATION_SCORE: score,
} = process.env;
const windowMs = CLOUD_AGENT_WINDOW * 60 * 1000;
const max = Number(CLOUD_AGENT_USER_MAX);
const handler = async (req, res) => {
const type = ViolationTypes.TOOL_CALL_LIMIT;
const errorMessage = {
type,
max,
limiter: 'user',
windowInMinutes: windowMs / 60000,
};
await logViolation(req, res, type, errorMessage, score);
res.status(429).json({ message: 'Too many cloud agent requests. Try again later.' });
};
const cloudAgentLimiter = rateLimit({
windowMs,
max,
handler,
keyGenerator: (req) => req.user?.id,
store: limiterCache('cloud_agent_limiter'),
});
module.exports = cloudAgentLimiter;