fix(cron): gate delivery prompt on message tool availability

This commit is contained in:
Ayaan Zaidi
2026-04-21 11:52:02 +05:30
parent 19e451dc75
commit b9d2e0f86d
2 changed files with 42 additions and 3 deletions

View File

@@ -19,13 +19,16 @@ import {
const runCronIsolatedAgentTurn = await loadRunCronIsolatedAgentTurn();
const { createCronPromptExecutor } = await import("./run-executor.js");
function makeMessageToolPolicyJob(delivery: Record<string, unknown> = { mode: "none" }) {
function makeMessageToolPolicyJob(
delivery: Record<string, unknown> = { mode: "none" },
payload: Record<string, unknown> = { kind: "agentTurn", message: "send a message" },
) {
return {
id: "message-tool-policy",
name: "Message Tool Policy",
schedule: { kind: "every", everyMs: 60_000 },
sessionTarget: "isolated",
payload: { kind: "agentTurn", message: "send a message" },
payload,
delivery,
} as never;
}
@@ -565,6 +568,29 @@ describe("runCronIsolatedAgentTurn delivery instruction", () => {
expect(prompt).not.toContain("note who/where");
});
it("does not prompt for the message tool when toolsAllow excludes it", async () => {
mockRunCronFallbackPassthrough();
resolveCronDeliveryPlanMock.mockReturnValue({
requested: true,
mode: "announce",
channel: "telegram",
to: "123",
});
await runCronIsolatedAgentTurn({
...makeParams(),
job: makeMessageToolPolicyJob(
{ mode: "announce", channel: "telegram", to: "123" },
{ kind: "agentTurn", message: "send a message", toolsAllow: ["read"] },
),
});
expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
const prompt: string = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
expect(prompt).not.toContain("Use the message tool");
expect(prompt).toContain("Return your response as plain text");
});
it("does not append a delivery instruction when delivery is not requested", async () => {
mockRunCronFallbackPassthrough();
resolveCronDeliveryPlanMock.mockReturnValue({ requested: false, mode: "none" });

View File

@@ -241,6 +241,16 @@ function resolveCronToolPolicy(params: { deliveryMode: "announce" | "webhook" |
};
}
function canPromptForMessageTool(params: {
disableMessageTool: boolean;
toolsAllow?: string[];
}): boolean {
if (params.disableMessageTool) {
return false;
}
return !params.toolsAllow?.length || params.toolsAllow.includes("message");
}
async function resolveCronDeliveryContext(params: {
cfg: OpenClawConfig;
job: CronJob;
@@ -561,7 +571,10 @@ async function prepareCronRunContext(params: {
commandBody = appendCronDeliveryInstruction({
commandBody,
deliveryRequested,
messageToolEnabled: !toolPolicy.disableMessageTool,
messageToolEnabled: canPromptForMessageTool({
disableMessageTool: toolPolicy.disableMessageTool,
toolsAllow: agentPayload?.toolsAllow,
}),
resolvedDeliveryOk: resolvedDelivery.ok,
});