mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 16:10:49 +00:00
fix(cron): preserve all fields in announce delivery by removing summarization instruction (#65638)
* fix(cron): preserve all fields in announce delivery by removing summarization instruction The delivery instruction appended to the cron agent prompt contained the word 'summary', causing LLMs to condense structured output non-deterministically and drop fields on delivery. Replace with 'response' and add explicit instruction to reproduce all fields exactly. Fixes #58535 * chore(changelog): add cron announce entry --------- Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
@@ -165,3 +165,71 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("runCronIsolatedAgentTurn delivery instruction", () => {
|
||||
let previousFastTestEnv: string | undefined;
|
||||
|
||||
beforeEach(() => {
|
||||
previousFastTestEnv = clearFastTestEnv();
|
||||
resetRunCronIsolatedAgentTurnHarness();
|
||||
resolveDeliveryTargetMock.mockResolvedValue({
|
||||
ok: true,
|
||||
channel: "telegram",
|
||||
to: "123",
|
||||
accountId: undefined,
|
||||
error: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
restoreFastTestEnv(previousFastTestEnv);
|
||||
});
|
||||
|
||||
it("appends a plain-text delivery instruction to the prompt when delivery is requested", async () => {
|
||||
mockRunCronFallbackPassthrough();
|
||||
resolveCronDeliveryPlanMock.mockReturnValue({
|
||||
requested: true,
|
||||
mode: "announce",
|
||||
channel: "telegram",
|
||||
to: "123",
|
||||
});
|
||||
|
||||
await runCronIsolatedAgentTurn(makeParams());
|
||||
|
||||
expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
|
||||
const prompt: string = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
|
||||
expect(prompt).toContain("Return your response as plain text");
|
||||
expect(prompt).toContain("it will be delivered automatically");
|
||||
});
|
||||
|
||||
it("does not append a delivery instruction when delivery is not requested", async () => {
|
||||
mockRunCronFallbackPassthrough();
|
||||
resolveCronDeliveryPlanMock.mockReturnValue({ requested: false, mode: "none" });
|
||||
|
||||
await runCronIsolatedAgentTurn(makeParams());
|
||||
|
||||
expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
|
||||
const prompt: string = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
|
||||
expect(prompt).not.toContain("Return your response as plain text");
|
||||
expect(prompt).not.toContain("it will be delivered automatically");
|
||||
});
|
||||
|
||||
it("does not instruct the agent to summarize when delivery is requested", async () => {
|
||||
// Regression for https://github.com/openclaw/openclaw/issues/58535:
|
||||
// "summary" caused LLMs to condense structured output and drop fields
|
||||
// non-deterministically on every run.
|
||||
mockRunCronFallbackPassthrough();
|
||||
resolveCronDeliveryPlanMock.mockReturnValue({
|
||||
requested: true,
|
||||
mode: "announce",
|
||||
channel: "telegram",
|
||||
to: "123",
|
||||
});
|
||||
|
||||
await runCronIsolatedAgentTurn(makeParams());
|
||||
|
||||
expect(runEmbeddedPiAgentMock).toHaveBeenCalledTimes(1);
|
||||
const prompt: string = runEmbeddedPiAgentMock.mock.calls[0]?.[0]?.prompt ?? "";
|
||||
expect(prompt).not.toMatch(/\bsummary\b/i);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -193,7 +193,7 @@ function appendCronDeliveryInstruction(params: {
|
||||
if (!params.deliveryRequested) {
|
||||
return params.commandBody;
|
||||
}
|
||||
return `${params.commandBody}\n\nReturn your summary as plain text; it will be delivered automatically. If the task explicitly calls for messaging a specific external recipient, note who/where it should go instead of sending it yourself.`.trim();
|
||||
return `${params.commandBody}\n\nReturn your response as plain text; it will be delivered automatically. If the task explicitly calls for messaging a specific external recipient, note who/where it should go instead of sending it yourself.`.trim();
|
||||
}
|
||||
|
||||
function resolvePositiveContextTokens(value: unknown): number | undefined {
|
||||
|
||||
Reference in New Issue
Block a user