fix: align exec default reporting with runtime

This commit is contained in:
Peter Steinberger
2026-04-08 04:37:06 +01:00
parent dce3abaef7
commit d9d9d357b4
3 changed files with 67 additions and 4 deletions

View File

@@ -4,6 +4,10 @@ Docs: https://docs.openclaw.ai
## Unreleased
### Fixes
- Agents/exec: keep `/exec` current-default reporting aligned with real runtime behavior so `host=auto` sessions surface the correct host-aware fallback policy (`full/off` on gateway or node, `deny/off` on sandbox) instead of stale stricter defaults.
## 2026.4.7
### Changes

View File

@@ -1,8 +1,17 @@
import { describe, expect, it } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { SessionEntry } from "../config/sessions.js";
import * as execApprovals from "../infra/exec-approvals.js";
import { resolveExecDefaults } from "./exec-defaults.js";
describe("resolveExecDefaults", () => {
beforeEach(() => {
vi.restoreAllMocks();
vi.spyOn(execApprovals, "loadExecApprovals").mockReturnValue({
version: 1,
agents: {},
});
});
it("does not advertise node routing when exec host is pinned to gateway", () => {
expect(
resolveExecDefaults({
@@ -55,4 +64,44 @@ describe("resolveExecDefaults", () => {
}).canRequestNode,
).toBe(true);
});
it("uses host approval defaults for gateway when exec policy is unset", () => {
expect(
resolveExecDefaults({
cfg: {
tools: {
exec: {
host: "auto",
},
},
},
sandboxAvailable: false,
}),
).toMatchObject({
host: "auto",
effectiveHost: "gateway",
security: "full",
ask: "off",
});
});
it("keeps sandbox deny by default when auto resolves to sandbox", () => {
expect(
resolveExecDefaults({
cfg: {
tools: {
exec: {
host: "auto",
},
},
},
sandboxAvailable: true,
}),
).toMatchObject({
host: "auto",
effectiveHost: "sandbox",
security: "deny",
ask: "off",
});
});
});

View File

@@ -1,6 +1,12 @@
import type { OpenClawConfig } from "../config/config.js";
import type { SessionEntry } from "../config/sessions.js";
import type { ExecAsk, ExecHost, ExecSecurity, ExecTarget } from "../infra/exec-approvals.js";
import {
loadExecApprovals,
type ExecAsk,
type ExecHost,
type ExecSecurity,
type ExecTarget,
} from "../infra/exec-approvals.js";
import { resolveAgentConfig, resolveSessionAgentId } from "./agent-scope.js";
import { isRequestedExecTargetAllowed, resolveExecTarget } from "./bash-tools.exec-runtime.js";
import { resolveSandboxRuntimeStatus } from "./sandbox/runtime-status.js";
@@ -88,6 +94,8 @@ export function resolveExecDefaults(params: {
elevatedRequested: false,
sandboxAvailable,
});
const approvalDefaults = loadExecApprovals().defaults;
const defaultSecurity = resolved.effectiveHost === "sandbox" ? "deny" : "full";
return {
host,
effectiveHost: resolved.effectiveHost,
@@ -95,12 +103,14 @@ export function resolveExecDefaults(params: {
(params.sessionEntry?.execSecurity as ExecSecurity | undefined) ??
agentExec?.security ??
globalExec?.security ??
"deny",
approvalDefaults?.security ??
defaultSecurity,
ask:
(params.sessionEntry?.execAsk as ExecAsk | undefined) ??
agentExec?.ask ??
globalExec?.ask ??
"on-miss",
approvalDefaults?.ask ??
"off",
node: params.sessionEntry?.execNode ?? agentExec?.node ?? globalExec?.node,
canRequestNode: isRequestedExecTargetAllowed({
configuredTarget: host,