fix: stabilize testbox test suite

This commit is contained in:
Peter Steinberger
2026-04-22 06:04:32 +01:00
parent 08d5ad3828
commit 0285afe86f
5 changed files with 37 additions and 23 deletions

View File

@@ -146,24 +146,28 @@ export function resolveAgentContextLimits(
return resolveAgentConfig(cfg, agentId)?.contextLimits ?? defaults;
}
export function resolveAgentWorkspaceDir(cfg: OpenClawConfig, agentId: string) {
export function resolveAgentWorkspaceDir(
cfg: OpenClawConfig,
agentId: string,
env: NodeJS.ProcessEnv = process.env,
) {
const id = normalizeAgentId(agentId);
const configured = resolveAgentConfig(cfg, id)?.workspace?.trim();
if (configured) {
return stripNullBytes(resolveUserPath(configured));
return stripNullBytes(resolveUserPath(configured, env));
}
const defaultAgentId = resolveDefaultAgentId(cfg);
const fallback = cfg.agents?.defaults?.workspace?.trim();
if (id === defaultAgentId) {
if (fallback) {
return stripNullBytes(resolveUserPath(fallback));
return stripNullBytes(resolveUserPath(fallback, env));
}
return stripNullBytes(resolveDefaultAgentWorkspaceDir(process.env));
return stripNullBytes(resolveDefaultAgentWorkspaceDir(env));
}
if (fallback) {
return stripNullBytes(path.join(resolveUserPath(fallback), id));
return stripNullBytes(path.join(resolveUserPath(fallback, env), id));
}
const stateDir = resolveStateDir(process.env);
const stateDir = resolveStateDir(env);
return stripNullBytes(path.join(stateDir, `workspace-${id}`));
}

View File

@@ -83,17 +83,23 @@ describe("resolveRunWorkspaceDir", () => {
});
it("uses explicit agent id for per-agent fallback when config is unavailable", () => {
const env = {
...process.env,
HOME: "/home/runner",
OPENCLAW_HOME: undefined,
OPENCLAW_STATE_DIR: "/tmp/openclaw-state",
} satisfies NodeJS.ProcessEnv;
const result = resolveRunWorkspaceDir({
workspaceDir: undefined,
sessionKey: "definitely-not-a-valid-session-key",
agentId: "research",
config: undefined,
env,
});
expect(result.agentId).toBe("research");
expect(result.agentIdSource).toBe("explicit");
expect(path.isAbsolute(result.workspaceDir)).toBe(true);
expect(path.basename(result.workspaceDir)).toBe("workspace-research");
expect(result.workspaceDir).toBe(path.resolve("/tmp/openclaw-state", "workspace-research"));
});
it("throws for malformed agent session keys even when config has a default agent", () => {

View File

@@ -76,7 +76,9 @@ export function resolveRunWorkspaceDir(params: {
sessionKey?: string;
agentId?: string;
config?: OpenClawConfig;
env?: NodeJS.ProcessEnv;
}): ResolveRunWorkspaceResult {
const env = params.env ?? process.env;
const requested = params.workspaceDir;
const { agentId, agentIdSource } = resolveRunAgentId({
sessionKey: params.sessionKey,
@@ -91,7 +93,7 @@ export function resolveRunWorkspaceDir(params: {
logWarn("Control/format characters stripped from workspaceDir (OC-19 hardening).");
}
return {
workspaceDir: resolveUserPath(sanitized),
workspaceDir: resolveUserPath(sanitized, env),
usedFallback: false,
agentId,
agentIdSource,
@@ -101,13 +103,13 @@ export function resolveRunWorkspaceDir(params: {
const fallbackReason: WorkspaceFallbackReason =
requested == null ? "missing" : typeof requested === "string" ? "blank" : "invalid_type";
const fallbackWorkspace = resolveAgentWorkspaceDir(params.config ?? {}, agentId);
const fallbackWorkspace = resolveAgentWorkspaceDir(params.config ?? {}, agentId, env);
const sanitizedFallback = sanitizeForPromptLiteral(fallbackWorkspace);
if (sanitizedFallback !== fallbackWorkspace) {
logWarn("Control/format characters stripped from fallback workspaceDir (OC-19 hardening).");
}
return {
workspaceDir: resolveUserPath(sanitizedFallback),
workspaceDir: resolveUserPath(sanitizedFallback, env),
usedFallback: true,
fallbackReason,
agentId,

View File

@@ -154,21 +154,11 @@ describe("doctor stale plugin config helpers", () => {
} as OpenClawConfig;
expect(scanStalePluginConfig(cfg)).toEqual([
{
pluginId: "openai-codex",
pathLabel: "plugins.allow",
surface: "allow",
},
{
pluginId: "acpx",
pathLabel: "plugins.allow",
surface: "allow",
},
{
pluginId: "openai-codex",
pathLabel: "plugins.entries.openai-codex",
surface: "entries",
},
{
pluginId: "acpx",
pathLabel: "plugins.entries.acpx",
@@ -177,7 +167,9 @@ describe("doctor stale plugin config helpers", () => {
]);
const result = maybeRepairStalePluginConfig(cfg);
expect(result.config.plugins?.allow).toEqual([]);
expect(result.config.plugins?.entries).toEqual({});
expect(result.config.plugins?.allow).toEqual(["openai-codex"]);
expect(result.config.plugins?.entries).toEqual({
"openai-codex": { enabled: true },
});
});
});

View File

@@ -34,6 +34,13 @@ export type NormalizedPluginsConfig = SharedNormalizedPluginsConfig;
let bundledPluginAliasLookupCache: ReadonlyMap<string, string> | undefined;
const BUILT_IN_PLUGIN_ALIAS_FALLBACKS: ReadonlyArray<readonly [alias: string, pluginId: string]> = [
["openai-codex", "openai"],
["google-gemini-cli", "google"],
["minimax-portal", "minimax"],
["minimax-portal-auth", "minimax"],
] as const;
function getBundledPluginAliasLookup(): ReadonlyMap<string, string> {
if (bundledPluginAliasLookupCache) {
return bundledPluginAliasLookupCache;
@@ -61,6 +68,9 @@ function getBundledPluginAliasLookup(): ReadonlyMap<string, string> {
}
}
}
for (const [alias, pluginId] of BUILT_IN_PLUGIN_ALIAS_FALLBACKS) {
lookup.set(alias, pluginId);
}
bundledPluginAliasLookupCache = lookup;
return lookup;
}