ai-chatbot/lib/openclaw-chat/cancel-registry.ts

77 lines
1.8 KiB
TypeScript

const CANCELED_REQUEST_TTL_MS = 10 * 60 * 1000;
type ActiveClawdRequest = {
controller: AbortController;
expiresAt: number;
};
const activeRequests = new Map<string, ActiveClawdRequest>();
const canceledRequests = new Map<string, number>();
function cleanupExpiredClawdRequests(now = Date.now()) {
for (const [key, request] of activeRequests.entries()) {
if (request.expiresAt <= now) {
activeRequests.delete(key);
}
}
for (const [key, expiresAt] of canceledRequests.entries()) {
if (expiresAt <= now) {
canceledRequests.delete(key);
}
}
}
export function buildClawdCancelKey({
userId,
chatId,
userMessageId,
}: {
userId: string;
chatId: string;
userMessageId: string;
}) {
return `${userId}:${chatId}:${userMessageId}`;
}
export function registerActiveClawdRequest(
key: string,
controller: AbortController,
timeoutMs: number
) {
cleanupExpiredClawdRequests();
activeRequests.set(key, {
controller,
expiresAt: Date.now() + Math.max(timeoutMs, CANCELED_REQUEST_TTL_MS),
});
}
export function unregisterActiveClawdRequest(key: string) {
activeRequests.delete(key);
}
export function cancelClawdRequest(key: string) {
cleanupExpiredClawdRequests();
canceledRequests.set(key, Date.now() + CANCELED_REQUEST_TTL_MS);
const activeRequest = activeRequests.get(key);
if (activeRequest && !activeRequest.controller.signal.aborted) {
activeRequest.controller.abort();
}
return Boolean(activeRequest);
}
export function isClawdRequestCanceled(key: string) {
cleanupExpiredClawdRequests();
const expiresAt = canceledRequests.get(key);
if (!expiresAt) return false;
if (expiresAt <= Date.now()) {
canceledRequests.delete(key);
return false;
}
return true;
}
export function clearClawdRequestCancellation(key: string) {
canceledRequests.delete(key);
}