diff --git a/package.json b/package.json index 79e03ff..08eeb0f 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ ] }, "scripts": { - "test": "node test/embedder-error-hints.test.mjs && node test/migrate-legacy-schema.test.mjs && node --test test/config-session-strategy-migration.test.mjs && node test/update-consistency-lancedb.test.mjs && node test/cli-smoke.mjs && node test/functional-e2e.mjs && node test/retriever-rerank-regression.mjs && node test/smart-memory-lifecycle.mjs && node test/smart-extractor-branches.mjs && node test/plugin-manifest-regression.mjs", + "test": "node test/embedder-error-hints.test.mjs && node test/migrate-legacy-schema.test.mjs && node --test test/config-session-strategy-migration.test.mjs && node test/update-consistency-lancedb.test.mjs && node test/cli-smoke.mjs && node test/functional-e2e.mjs && node test/retriever-rerank-regression.mjs && node test/smart-memory-lifecycle.mjs && node test/smart-extractor-branches.mjs && node test/plugin-manifest-regression.mjs && node --test test/adaptive-retrieval-skip-heartbeat.test.mjs", "test:openclaw-host": "node test/openclaw-host-functional.mjs" }, "devDependencies": { diff --git a/src/adaptive-retrieval.ts b/src/adaptive-retrieval.ts index 88770aa..736d719 100644 --- a/src/adaptive-retrieval.ts +++ b/src/adaptive-retrieval.ts @@ -20,6 +20,8 @@ const SKIP_PATTERNS = [ /^[\p{Emoji}\s]+$/u, // Heartbeat/system (match anywhere, not just at start, to handle prefixed formats) /HEARTBEAT/i, + /^(no[_-]?reply|noreply)\s*[.!]?$/i, + /^(heartbeat(_ok|_fail|_err|_error)?|heartbeat\s*(ok|fail|error)|health[_ -]?check|system[_ -]?check|status[_ -]?check)\s*[.!]?$/i, /^\[System/i, // Single-word utility pings /^(ping|pong|test|debug)\s*[.!?]?$/i, @@ -57,6 +59,10 @@ function normalizeQuery(query: string): string { // 3. Strip OpenClaw timestamp prefix [Mon 2026-03-02 04:21 GMT+8]. s = s.trim().replace(/^\[[A-Za-z]{3}\s\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s[^\]]+\]\s*/, ""); + // 4. Strip heartbeat/healthcheck wrappers. + s = s.trim().replace(/^\[(heartbeat|health[-_ ]?check|system[-_ ]?check)[^\]]*\]\s*/i, ""); + s = s.trim().replace(/^(heartbeat|health[-_ ]?check|system[-_ ]?check)\s*[:\-]\s*/i, ""); + const result = s.trim(); return result; } diff --git a/test/adaptive-retrieval-skip-heartbeat.test.mjs b/test/adaptive-retrieval-skip-heartbeat.test.mjs new file mode 100644 index 0000000..2641835 --- /dev/null +++ b/test/adaptive-retrieval-skip-heartbeat.test.mjs @@ -0,0 +1,27 @@ +import { describe, it } from "node:test"; +import assert from "node:assert/strict"; +import jitiFactory from "jiti"; + +const jiti = jitiFactory(import.meta.url, { interopDefault: true }); + +const { shouldSkipRetrieval } = jiti("../src/adaptive-retrieval.ts"); + +describe("shouldSkipRetrieval heartbeat/NO_REPLY", () => { + const cases = [ + "NO_REPLY", + "no_reply", + "no-reply", + "HEARTBEAT_OK", + "heartbeat ok", + "heartbeat: NO_REPLY", + "[heartbeat] NO_REPLY", + "health_check", + "system-check", + ]; + + for (const input of cases) { + it(`skips retrieval for ${input}`, () => { + assert.equal(shouldSkipRetrieval(input), true); + }); + } +});