diff --git a/extensions/mattermost/src/mattermost/monitor-helpers.ts b/extensions/mattermost/src/mattermost/monitor-helpers.ts index 9e483f6a46b..7f3d6edf7e2 100644 --- a/extensions/mattermost/src/mattermost/monitor-helpers.ts +++ b/extensions/mattermost/src/mattermost/monitor-helpers.ts @@ -2,6 +2,8 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk"; import type WebSocket from "ws"; import { Buffer } from "node:buffer"; +export { createDedupeCache } from "openclaw/plugin-sdk"; + export type ResponsePrefixContext = { model?: string; modelFull?: string; @@ -38,59 +40,6 @@ export function formatInboundFromLabel(params: { return `${directLabel} id:${directId}`; } -type DedupeCache = { - check: (key: string | undefined | null, now?: number) => boolean; -}; - -export function createDedupeCache(options: { ttlMs: number; maxSize: number }): DedupeCache { - const ttlMs = Math.max(0, options.ttlMs); - const maxSize = Math.max(0, Math.floor(options.maxSize)); - const cache = new Map(); - - const touch = (key: string, now: number) => { - cache.delete(key); - cache.set(key, now); - }; - - const prune = (now: number) => { - const cutoff = ttlMs > 0 ? now - ttlMs : undefined; - if (cutoff !== undefined) { - for (const [entryKey, entryTs] of cache) { - if (entryTs < cutoff) { - cache.delete(entryKey); - } - } - } - if (maxSize <= 0) { - cache.clear(); - return; - } - while (cache.size > maxSize) { - const oldestKey = cache.keys().next().value as string | undefined; - if (!oldestKey) { - break; - } - cache.delete(oldestKey); - } - }; - - return { - check: (key, now = Date.now()) => { - if (!key) { - return false; - } - const existing = cache.get(key); - if (existing !== undefined && (ttlMs <= 0 || now - existing < ttlMs)) { - touch(key, now); - return true; - } - touch(key, now); - prune(now); - return false; - }, - }; -} - export function rawDataToString( data: WebSocket.RawData, encoding: BufferEncoding = "utf8", diff --git a/src/plugin-sdk/index.ts b/src/plugin-sdk/index.ts index e50ab9dbf36..7a7634b0bc2 100644 --- a/src/plugin-sdk/index.ts +++ b/src/plugin-sdk/index.ts @@ -141,6 +141,8 @@ export { listDevicePairing, rejectDevicePairing, } from "../infra/device-pairing.js"; +export { createDedupeCache } from "../infra/dedupe.js"; +export type { DedupeCache } from "../infra/dedupe.js"; export { formatErrorMessage } from "../infra/errors.js"; export { DEFAULT_WEBHOOK_BODY_TIMEOUT_MS,