From 208bed06e121cd76a1d27d13d62e22b238d17e2e Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 20 Jun 2026 08:12:44 +0800 Subject: [PATCH] refactor(qa): share progress formatting helpers --- .../telegram/telegram-live.runtime.ts | 32 +++---------------- extensions/qa-lab/src/progress-format.ts | 27 ++++++++++++++++ extensions/qa-lab/src/suite.ts | 32 +++---------------- 3 files changed, 35 insertions(+), 56 deletions(-) create mode 100644 extensions/qa-lab/src/progress-format.ts diff --git a/extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts b/extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts index 94a6c6b9ac31..e93ba4af5671 100644 --- a/extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts +++ b/extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts @@ -18,6 +18,10 @@ import { } from "../../evidence-summary.js"; import { startQaGatewayChild } from "../../gateway-child.js"; import { isTruthyOptIn } from "../../mantis-options.runtime.js"; +import { + parseQaProgressBooleanEnv as parseTelegramQaProgressBooleanEnv, + sanitizeQaProgressValue as sanitizeTelegramQaProgressValue, +} from "../../progress-format.js"; import { DEFAULT_QA_LIVE_PROVIDER_MODE } from "../../providers/index.js"; import { defaultQaModelForMode, @@ -574,20 +578,6 @@ function readConfigRecord(root: Record, key: string): Record= 0x7f && code <= 0x9f); - normalized += isControl ? " " : char; - } - normalized = normalized.replace(/\s+/gu, " ").trim(); - return normalized.length > 0 ? normalized : ""; -} - function formatTelegramQaProgressDetails(details: string): string { const sanitized = sanitizeTelegramQaProgressValue(details); if (sanitized.length <= TELEGRAM_QA_PROGRESS_DETAIL_LIMIT) { diff --git a/extensions/qa-lab/src/progress-format.ts b/extensions/qa-lab/src/progress-format.ts new file mode 100644 index 000000000000..615ffca4af57 --- /dev/null +++ b/extensions/qa-lab/src/progress-format.ts @@ -0,0 +1,27 @@ +export function parseQaProgressBooleanEnv(value: string | undefined): boolean | undefined { + const normalized = value?.trim().toLowerCase(); + if (!normalized) { + return undefined; + } + if (normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on") { + return true; + } + if (normalized === "0" || normalized === "false" || normalized === "no" || normalized === "off") { + return false; + } + return undefined; +} + +export function sanitizeQaProgressValue(value: string): string { + let normalized = ""; + for (const char of value) { + const code = char.codePointAt(0); + if (code === undefined) { + continue; + } + const isControl = code <= 0x1f || (code >= 0x7f && code <= 0x9f); + normalized += isControl ? " " : char; + } + normalized = normalized.replace(/\s+/gu, " ").trim(); + return normalized.length > 0 ? normalized : ""; +} diff --git a/extensions/qa-lab/src/suite.ts b/extensions/qa-lab/src/suite.ts index 055697cebf6f..9915c722a14f 100644 --- a/extensions/qa-lab/src/suite.ts +++ b/extensions/qa-lab/src/suite.ts @@ -27,6 +27,10 @@ import { normalizeQaProviderMode, type QaProviderMode, } from "./model-selection.js"; +import { + parseQaProgressBooleanEnv as parseQaSuiteBooleanEnv, + sanitizeQaProgressValue as sanitizeQaSuiteProgressValue, +} from "./progress-format.js"; import { DEFAULT_QA_LIVE_PROVIDER_MODE } from "./providers/index.js"; import { startQaProviderServer } from "./providers/server-runtime.js"; import type { QaThinkingLevel } from "./qa-gateway-config.js"; @@ -124,20 +128,6 @@ export type QaSuiteRunParams = { captureRuntimeParityCell?: boolean; }; -function parseQaSuiteBooleanEnv(value: string | undefined): boolean | undefined { - const normalized = value?.trim().toLowerCase(); - if (!normalized) { - return undefined; - } - if (normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on") { - return true; - } - if (normalized === "0" || normalized === "false" || normalized === "no" || normalized === "off") { - return false; - } - return undefined; -} - function shouldLogQaSuiteProgress(env: NodeJS.ProcessEnv = process.env) { const override = parseQaSuiteBooleanEnv(env.OPENCLAW_QA_SUITE_PROGRESS); if (override !== undefined) { @@ -214,20 +204,6 @@ async function waitForQaLabReadyOrStopOwned(params: { } } -function sanitizeQaSuiteProgressValue(value: string): string { - let normalized = ""; - for (const char of value) { - const code = char.codePointAt(0); - if (code === undefined) { - continue; - } - const isControl = code <= 0x1f || (code >= 0x7f && code <= 0x9f); - normalized += isControl ? " " : char; - } - normalized = normalized.replace(/\s+/gu, " ").trim(); - return normalized.length > 0 ? normalized : ""; -} - function requireQaSuiteStartLab(startLab: QaSuiteStartLabFn | undefined): QaSuiteStartLabFn { if (startLab) { return startLab;