mirror of
https://github.com/farcasclaudiu/openclaw.git
synced 2026-06-29 09:02:02 +03:00
perf(test): speed up vitest by skipping plugins + LLM slug
This commit is contained in:
@@ -39,12 +39,30 @@ const resolvedOverride =
|
|||||||
const parallelRuns = runs.filter((entry) => entry.name !== "gateway");
|
const parallelRuns = runs.filter((entry) => entry.name !== "gateway");
|
||||||
const serialRuns = runs.filter((entry) => entry.name === "gateway");
|
const serialRuns = runs.filter((entry) => entry.name === "gateway");
|
||||||
const localWorkers = Math.max(4, Math.min(16, os.cpus().length));
|
const localWorkers = Math.max(4, Math.min(16, os.cpus().length));
|
||||||
const parallelCount = Math.max(1, parallelRuns.length);
|
const defaultUnitWorkers = localWorkers;
|
||||||
const perRunWorkers = Math.max(1, Math.floor(localWorkers / parallelCount));
|
const defaultExtensionsWorkers = Math.max(1, Math.min(4, Math.floor(localWorkers / 4)));
|
||||||
const macCiWorkers = isCI && isMacOS ? 1 : perRunWorkers;
|
const defaultGatewayWorkers = Math.max(1, Math.min(4, localWorkers));
|
||||||
|
|
||||||
// Keep worker counts predictable for local runs; trim macOS CI workers to avoid worker crashes/OOM.
|
// Keep worker counts predictable for local runs; trim macOS CI workers to avoid worker crashes/OOM.
|
||||||
// In CI on linux/windows, prefer Vitest defaults to avoid cross-test interference from lower worker counts.
|
// In CI on linux/windows, prefer Vitest defaults to avoid cross-test interference from lower worker counts.
|
||||||
const maxWorkers = resolvedOverride ?? (isCI && !isMacOS ? null : macCiWorkers);
|
const maxWorkersForRun = (name) => {
|
||||||
|
if (resolvedOverride) {
|
||||||
|
return resolvedOverride;
|
||||||
|
}
|
||||||
|
if (isCI && !isMacOS) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (isCI && isMacOS) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (name === "extensions") {
|
||||||
|
return defaultExtensionsWorkers;
|
||||||
|
}
|
||||||
|
if (name === "gateway") {
|
||||||
|
return defaultGatewayWorkers;
|
||||||
|
}
|
||||||
|
return defaultUnitWorkers;
|
||||||
|
};
|
||||||
|
|
||||||
const WARNING_SUPPRESSION_FLAGS = [
|
const WARNING_SUPPRESSION_FLAGS = [
|
||||||
"--disable-warning=ExperimentalWarning",
|
"--disable-warning=ExperimentalWarning",
|
||||||
@@ -54,6 +72,7 @@ const WARNING_SUPPRESSION_FLAGS = [
|
|||||||
|
|
||||||
const runOnce = (entry, extraArgs = []) =>
|
const runOnce = (entry, extraArgs = []) =>
|
||||||
new Promise((resolve) => {
|
new Promise((resolve) => {
|
||||||
|
const maxWorkers = maxWorkersForRun(entry.name);
|
||||||
const args = maxWorkers
|
const args = maxWorkers
|
||||||
? [...entry.args, "--maxWorkers", String(maxWorkers), ...windowsCiArgs, ...extraArgs]
|
? [...entry.args, "--maxWorkers", String(maxWorkers), ...windowsCiArgs, ...extraArgs]
|
||||||
: [...entry.args, ...windowsCiArgs, ...extraArgs];
|
: [...entry.args, ...windowsCiArgs, ...extraArgs];
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent
|
|||||||
import { loadConfig } from "../config/config.js";
|
import { loadConfig } from "../config/config.js";
|
||||||
import { createSubsystemLogger } from "../logging.js";
|
import { createSubsystemLogger } from "../logging.js";
|
||||||
import { loadOpenClawPlugins } from "../plugins/loader.js";
|
import { loadOpenClawPlugins } from "../plugins/loader.js";
|
||||||
|
import { getActivePluginRegistry } from "../plugins/runtime.js";
|
||||||
|
|
||||||
const log = createSubsystemLogger("plugins");
|
const log = createSubsystemLogger("plugins");
|
||||||
let pluginRegistryLoaded = false;
|
let pluginRegistryLoaded = false;
|
||||||
@@ -11,6 +12,16 @@ export function ensurePluginRegistryLoaded(): void {
|
|||||||
if (pluginRegistryLoaded) {
|
if (pluginRegistryLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const active = getActivePluginRegistry();
|
||||||
|
// Tests (and callers) can pre-seed a registry (e.g. `test/setup.ts`); avoid
|
||||||
|
// doing an expensive load when we already have plugins/channels/tools.
|
||||||
|
if (
|
||||||
|
active &&
|
||||||
|
(active.plugins.length > 0 || active.channels.length > 0 || active.tools.length > 0)
|
||||||
|
) {
|
||||||
|
pluginRegistryLoaded = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
const config = loadConfig();
|
const config = loadConfig();
|
||||||
const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
|
const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
|
||||||
const logger: PluginLogger = {
|
const logger: PluginLogger = {
|
||||||
|
|||||||
@@ -59,7 +59,10 @@ const HookConfigSchema = z
|
|||||||
enabled: z.boolean().optional(),
|
enabled: z.boolean().optional(),
|
||||||
env: z.record(z.string(), z.string()).optional(),
|
env: z.record(z.string(), z.string()).optional(),
|
||||||
})
|
})
|
||||||
.strict();
|
// Hook configs are intentionally open-ended (handlers can define their own keys).
|
||||||
|
// Keep enabled/env typed, but allow additional per-hook keys without marking the
|
||||||
|
// whole config invalid (which triggers doctor/best-effort loads).
|
||||||
|
.passthrough();
|
||||||
|
|
||||||
const HookInstallRecordSchema = z
|
const HookInstallRecordSchema = z
|
||||||
.object({
|
.object({
|
||||||
|
|||||||
@@ -122,8 +122,15 @@ const saveSessionToMemory: HookHandler = async (event) => {
|
|||||||
messageCount,
|
messageCount,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Avoid calling the model provider in unit tests, keep hooks fast and deterministic.
|
// Avoid calling the model provider in unit tests; keep hooks fast and deterministic.
|
||||||
if (sessionContent && cfg && !process.env.VITEST && process.env.NODE_ENV !== "test") {
|
const isTestEnv =
|
||||||
|
process.env.OPENCLAW_TEST_FAST === "1" ||
|
||||||
|
process.env.VITEST === "true" ||
|
||||||
|
process.env.VITEST === "1" ||
|
||||||
|
process.env.NODE_ENV === "test";
|
||||||
|
const allowLlmSlug = !isTestEnv && hookConfig?.llmSlug !== false;
|
||||||
|
|
||||||
|
if (sessionContent && cfg && allowLlmSlug) {
|
||||||
log.debug("Calling generateSlugViaLLM...");
|
log.debug("Calling generateSlugViaLLM...");
|
||||||
// Use LLM to generate a descriptive slug
|
// Use LLM to generate a descriptive slug
|
||||||
slug = await generateSlugViaLLM({ sessionContent, cfg });
|
slug = await generateSlugViaLLM({ sessionContent, cfg });
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { createSubsystemLogger } from "../logging/subsystem.js";
|
|||||||
import { resolveUserPath } from "../utils.js";
|
import { resolveUserPath } from "../utils.js";
|
||||||
import { clearPluginCommands } from "./commands.js";
|
import { clearPluginCommands } from "./commands.js";
|
||||||
import {
|
import {
|
||||||
|
applyTestPluginDefaults,
|
||||||
normalizePluginsConfig,
|
normalizePluginsConfig,
|
||||||
resolveEnableState,
|
resolveEnableState,
|
||||||
resolveMemorySlotDecision,
|
resolveMemorySlotDecision,
|
||||||
@@ -167,7 +168,9 @@ function pushDiagnostics(diagnostics: PluginDiagnostic[], append: PluginDiagnost
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegistry {
|
export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegistry {
|
||||||
const cfg = options.config ?? {};
|
// Test env: default-disable plugins unless explicitly configured.
|
||||||
|
// This keeps unit/gateway suites fast and avoids loading heavyweight plugin deps by accident.
|
||||||
|
const cfg = applyTestPluginDefaults(options.config ?? {}, process.env);
|
||||||
const logger = options.logger ?? defaultLogger();
|
const logger = options.logger ?? defaultLogger();
|
||||||
const validateOnly = options.mode === "validate";
|
const validateOnly = options.mode === "validate";
|
||||||
const normalized = normalizePluginsConfig(cfg.plugins);
|
const normalized = normalizePluginsConfig(cfg.plugins);
|
||||||
|
|||||||
+10
-1
@@ -2,6 +2,7 @@ import type { AnyAgentTool } from "../agents/tools/common.js";
|
|||||||
import type { OpenClawPluginToolContext } from "./types.js";
|
import type { OpenClawPluginToolContext } from "./types.js";
|
||||||
import { normalizeToolName } from "../agents/tool-policy.js";
|
import { normalizeToolName } from "../agents/tool-policy.js";
|
||||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||||
|
import { applyTestPluginDefaults, normalizePluginsConfig } from "./config-state.js";
|
||||||
import { loadOpenClawPlugins } from "./loader.js";
|
import { loadOpenClawPlugins } from "./loader.js";
|
||||||
|
|
||||||
const log = createSubsystemLogger("plugins");
|
const log = createSubsystemLogger("plugins");
|
||||||
@@ -45,8 +46,16 @@ export function resolvePluginTools(params: {
|
|||||||
existingToolNames?: Set<string>;
|
existingToolNames?: Set<string>;
|
||||||
toolAllowlist?: string[];
|
toolAllowlist?: string[];
|
||||||
}): AnyAgentTool[] {
|
}): AnyAgentTool[] {
|
||||||
|
// Fast path: when plugins are effectively disabled, avoid discovery/jiti entirely.
|
||||||
|
// This matters a lot for unit tests and for tool construction hot paths.
|
||||||
|
const effectiveConfig = applyTestPluginDefaults(params.context.config ?? {}, process.env);
|
||||||
|
const normalized = normalizePluginsConfig(effectiveConfig.plugins);
|
||||||
|
if (!normalized.enabled) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const registry = loadOpenClawPlugins({
|
const registry = loadOpenClawPlugins({
|
||||||
config: params.context.config,
|
config: effectiveConfig,
|
||||||
workspaceDir: params.context.workspaceDir,
|
workspaceDir: params.context.workspaceDir,
|
||||||
logger: {
|
logger: {
|
||||||
info: (msg) => log.info(msg),
|
info: (msg) => log.info(msg),
|
||||||
|
|||||||
Reference in New Issue
Block a user