import path from "node:path"; import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime"; import { ensureRepoBoundDirectory, resolveRepoRelativeOutputDir } from "./cli-paths.js"; import type { QaCliBackendAuthMode } from "./gateway-child.js"; import type { QaProviderMode } from "./model-selection.js"; import { getQaProvider } from "./providers/index.js"; import type { QaTransportId } from "./qa-transport-registry.js"; import { readQaBootstrapScenarioCatalog } from "./scenario-catalog.js";
function isQaPlainObject(value: unknown): value is Record<string, unknown> { return value !== null && typeof value === "object" && !Array.isArray(value);
}
function applyQaMergePatch(base: unknown, patch: unknown): unknown { if (!isQaPlainObject(patch)) { return patch;
} const result = isQaPlainObject(base) ? { ...base } : {}; for (const [key, value] of Object.entries(patch)) { if (QA_MERGE_PATCH_BLOCKED_KEYS.has(key)) { continue;
} if (value === null) { delete result[key]; continue;
}
result[key] = isQaPlainObject(value) ? applyQaMergePatch(result[key], value) : value;
} return result;
}
function collectQaSuiteGatewayConfigPatch(
scenarios: ReturnType<typeof readQaBootstrapScenarioCatalog>["scenarios"],
): Record<string, unknown> | undefined {
let merged: Record<string, unknown> | undefined; for (const scenario of scenarios) { if (!isQaPlainObject(scenario.gatewayConfigPatch)) { continue;
}
merged = applyQaMergePatch(merged ?? {}, scenario.gatewayConfigPatch) as Record<
string,
unknown
>;
} return merged;
}
function collectQaSuiteGatewayRuntimeOptions(
scenarios: ReturnType<typeof readQaBootstrapScenarioCatalog>["scenarios"],
) {
let forwardHostHome = false; for (const scenario of scenarios) { if (scenario.gatewayRuntime?.forwardHostHome === true) {
forwardHostHome = true;
}
} return forwardHostHome ? { forwardHostHome: true } : undefined;
}
function scenarioRequiresControlUi(scenario: QaSeedScenario) { return normalizeLowercaseStringOrEmpty(scenario.surface) === "control-ui";
}
function normalizeQaSuiteConcurrency(
value: number | undefined,
scenarioCount: number,
defaultConcurrency = DEFAULT_QA_SUITE_CONCURRENCY,
) { const envValue = Number(process.env.OPENCLAW_QA_SUITE_CONCURRENCY); const raw = typeof value === "number" && Number.isFinite(value)
? value
: Number.isFinite(envValue)
? envValue
: defaultConcurrency; return Math.max(1, Math.min(Math.floor(raw), Math.max(1, scenarioCount)));
}
function resolveQaSuiteWorkerStartStaggerMs(
concurrency: number,
env: NodeJS.ProcessEnv = process.env,
) { if (concurrency <= 1) { return0;
} const raw = env.OPENCLAW_QA_SUITE_WORKER_START_STAGGER_MS; if (raw === undefined) { return DEFAULT_QA_SUITE_WORKER_START_STAGGER_MS;
} const parsed = Number(raw); if (!Number.isFinite(parsed) || parsed < 0) { return DEFAULT_QA_SUITE_WORKER_START_STAGGER_MS;
} return Math.floor(parsed);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.