mirror of
https://github.com/hanzoai/bot.git
synced 2026-11-02 07:30:08 +00:00
Comprehensive rename of all openclaw references to hanzo-bot equivalents: - Package: openclaw → @hanzo/bot - Binary: openclaw → hanzo-bot - Types: OpenClaw* → Bot* - Env vars: OPENCLAW_* → BOT_* - Android: ai.openclaw.android → ai.hanzo.bot.android - iOS/macOS: ai.openclaw.* → ai.hanzo.* - Swift modules: OpenClaw* → Bot* - Plugins: openclaw.plugin.json → bot.plugin.json - Paths: .openclaw/ → .hanzo/bot/ - URLs: github.com/openclaw → github.com/hanzoai
55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
import os from "node:os";
|
|
import path from "node:path";
|
|
import { createDedupeCache, createPersistentDedupe } from "bot/plugin-sdk";
|
|
|
|
// Persistent TTL: 24 hours — survives restarts & WebSocket reconnects.
|
|
const DEDUP_TTL_MS = 24 * 60 * 60 * 1000;
|
|
const MEMORY_MAX_SIZE = 1_000;
|
|
const FILE_MAX_ENTRIES = 10_000;
|
|
|
|
const memoryDedupe = createDedupeCache({ ttlMs: DEDUP_TTL_MS, maxSize: MEMORY_MAX_SIZE });
|
|
|
|
function resolveStateDirFromEnv(env: NodeJS.ProcessEnv = process.env): string {
|
|
const stateOverride = env.BOT_STATE_DIR?.trim() || env.BOT_STATE_DIR?.trim();
|
|
if (stateOverride) {
|
|
return stateOverride;
|
|
}
|
|
if (env.VITEST || env.NODE_ENV === "test") {
|
|
return path.join(os.tmpdir(), ["bot-vitest", String(process.pid)].join("-"));
|
|
}
|
|
return path.join(os.homedir(), ".hanzo/bot");
|
|
}
|
|
|
|
function resolveNamespaceFilePath(namespace: string): string {
|
|
const safe = namespace.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
return path.join(resolveStateDirFromEnv(), "feishu", "dedup", `${safe}.json`);
|
|
}
|
|
|
|
const persistentDedupe = createPersistentDedupe({
|
|
ttlMs: DEDUP_TTL_MS,
|
|
memoryMaxSize: MEMORY_MAX_SIZE,
|
|
fileMaxEntries: FILE_MAX_ENTRIES,
|
|
resolveFilePath: resolveNamespaceFilePath,
|
|
});
|
|
|
|
/**
|
|
* Synchronous dedup — memory only.
|
|
* Kept for backward compatibility; prefer {@link tryRecordMessagePersistent}.
|
|
*/
|
|
export function tryRecordMessage(messageId: string): boolean {
|
|
return !memoryDedupe.check(messageId);
|
|
}
|
|
|
|
export async function tryRecordMessagePersistent(
|
|
messageId: string,
|
|
namespace = "global",
|
|
log?: (...args: unknown[]) => void,
|
|
): Promise<boolean> {
|
|
return persistentDedupe.checkAndRecord(messageId, {
|
|
namespace,
|
|
onDiskError: (error) => {
|
|
log?.(`feishu-dedup: disk error, falling back to memory: ${String(error)}`);
|
|
},
|
|
});
|
|
}
|