/** * AtoCore capture hook for OpenClaw. * * Listens on message:received (buffer prompt) and message:sent (POST pair). * Fail-open: errors are caught silently. */ const BASE_URL = process.env.ATOCORE_BASE_URL || "http://dalidou:8100"; const MIN_LEN = 15; const MAX_RESP = 50000; let lastPrompt = null; // simple single-slot buffer const atocoreCaptureHook = async (event) => { try { if (process.env.ATOCORE_CAPTURE_DISABLED === "1") return; if (event.type === "message" && event.action === "received") { const content = (event.context?.content || "").trim(); if (content.length >= MIN_LEN && !content.startsWith("<")) { lastPrompt = { text: content, ts: Date.now() }; } return; } if (event.type === "message" && event.action === "sent") { if (!event.context?.success) return; const response = (event.context?.content || "").trim(); if (!response || !lastPrompt) return; // Discard stale prompts (>5 min old) if (Date.now() - lastPrompt.ts > 300000) { lastPrompt = null; return; } const prompt = lastPrompt.text; lastPrompt = null; const body = JSON.stringify({ prompt, response: response.length > MAX_RESP ? response.slice(0, MAX_RESP) + "\n\n[truncated]" : response, client: "openclaw", session_id: event.sessionKey || "", project: "", reinforce: true, }); fetch(BASE_URL.replace(/\/$/, "") + "/interactions", { method: "POST", headers: { "Content-Type": "application/json" }, body, signal: AbortSignal.timeout(10000), }).catch(() => {}); } } catch { // fail-open: never crash the gateway } }; export default atocoreCaptureHook;