Files
openclaw/src/auto-reply/reply.directive.exec-agent-defaults.test.ts
pgondhi987 6d341cf366 fix(auto-reply): thread per-agent tools.exec defaults into reply directives (#57689)
* fix(auto-reply): thread per-agent tools.exec defaults into exec overrides

* test(auto-reply): add session-override and inline-directive priority tests for exec agent defaults
2026-03-30 16:46:54 +01:00

162 lines
4.4 KiB
TypeScript

import fs from "node:fs/promises";
import "./reply.directive.directive-behavior.e2e-mocks.js";
import { beforeEach, describe, expect, it, vi } from "vitest";
import {
DEFAULT_TEST_MODEL_CATALOG,
MAIN_SESSION_KEY,
installDirectiveBehaviorE2EHooks,
installFreshDirectiveBehaviorReplyMocks,
makeEmbeddedTextResult,
sessionStorePath,
withTempHome,
} from "./reply.directive.directive-behavior.e2e-harness.js";
import {
loadModelCatalogMock,
runEmbeddedPiAgentMock,
} from "./reply.directive.directive-behavior.e2e-mocks.js";
let getReplyFromConfig: typeof import("./reply/get-reply.js").getReplyFromConfig;
function makeAgentExecConfig(home: string) {
return {
agents: {
defaults: {
model: "anthropic/claude-opus-4-5",
workspace: `${home}/openclaw`,
},
list: [
{
id: "main",
tools: {
exec: {
host: "node" as const,
security: "allowlist" as const,
ask: "always" as const,
node: "worker-alpha",
},
},
},
],
},
channels: { whatsapp: { allowFrom: ["*"] } },
session: { store: sessionStorePath(home) },
};
}
describe("directive behavior exec agent defaults", () => {
installDirectiveBehaviorE2EHooks();
beforeEach(async () => {
vi.resetModules();
loadModelCatalogMock.mockReset();
loadModelCatalogMock.mockResolvedValue(DEFAULT_TEST_MODEL_CATALOG);
installFreshDirectiveBehaviorReplyMocks();
({ getReplyFromConfig } = await import("./reply/get-reply.js"));
});
it("threads per-agent tools.exec defaults into live runs without a persisted session override", async () => {
await withTempHome(async (home) => {
runEmbeddedPiAgentMock.mockResolvedValue(makeEmbeddedTextResult("done"));
await getReplyFromConfig(
{
Body: "run a command",
From: "+1004",
To: "+2000",
Provider: "whatsapp",
SenderE164: "+1004",
},
{},
makeAgentExecConfig(home),
);
expect(runEmbeddedPiAgentMock).toHaveBeenCalledOnce();
const call = runEmbeddedPiAgentMock.mock.calls[0]?.[0];
expect(call?.execOverrides).toEqual({
host: "node",
security: "allowlist",
ask: "always",
node: "worker-alpha",
});
});
});
it("prefers standalone inline exec directives over per-agent exec defaults on the next live run", async () => {
await withTempHome(async (home) => {
runEmbeddedPiAgentMock.mockResolvedValue(makeEmbeddedTextResult("done"));
await getReplyFromConfig(
{
Body: "/exec host=auto",
From: "+1004",
To: "+2000",
CommandAuthorized: true,
},
{},
makeAgentExecConfig(home),
);
runEmbeddedPiAgentMock.mockClear();
await getReplyFromConfig(
{
Body: "run a command",
From: "+1004",
To: "+2000",
Provider: "whatsapp",
SenderE164: "+1004",
},
{},
makeAgentExecConfig(home),
);
expect(runEmbeddedPiAgentMock).toHaveBeenCalledOnce();
const call = runEmbeddedPiAgentMock.mock.calls[0]?.[0];
expect(call?.execOverrides).toEqual({
host: "auto",
security: "allowlist",
ask: "always",
node: "worker-alpha",
});
});
});
it("prefers persisted session exec overrides over per-agent exec defaults", async () => {
await withTempHome(async (home) => {
runEmbeddedPiAgentMock.mockResolvedValue(makeEmbeddedTextResult("done"));
await fs.writeFile(
sessionStorePath(home),
JSON.stringify({
[MAIN_SESSION_KEY]: {
sessionId: "main",
updatedAt: Date.now(),
execHost: "auto",
},
}),
"utf-8",
);
await getReplyFromConfig(
{
Body: "run a command",
From: "+1004",
To: "+2000",
Provider: "whatsapp",
SenderE164: "+1004",
},
{},
makeAgentExecConfig(home),
);
expect(runEmbeddedPiAgentMock).toHaveBeenCalledOnce();
const call = runEmbeddedPiAgentMock.mock.calls[0]?.[0];
expect(call?.execOverrides).toEqual({
host: "auto",
security: "allowlist",
ask: "always",
node: "worker-alpha",
});
});
});
});