mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:30:43 +00:00
fix: harden finalize retry metadata
This commit is contained in:
@@ -97,6 +97,41 @@ describe("before_agent_finalize hook runner", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("skips malformed retry instructions when merging revise decisions", async () => {
|
||||
const runner = createHookRunner(
|
||||
createMockPluginRegistry([
|
||||
{
|
||||
hookName: "before_agent_finalize",
|
||||
handler: vi.fn().mockResolvedValue({
|
||||
action: "revise",
|
||||
reason: "malformed retry payload should not crash",
|
||||
retry: { instruction: 123, idempotencyKey: "bad-retry" } as never,
|
||||
}),
|
||||
},
|
||||
{
|
||||
hookName: "before_agent_finalize",
|
||||
handler: vi.fn().mockResolvedValue({
|
||||
action: "revise",
|
||||
reason: "valid retry still applies",
|
||||
retry: {
|
||||
instruction: " rerun the focused tests ",
|
||||
idempotencyKey: "valid-retry",
|
||||
},
|
||||
}),
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
await expect(runner.runBeforeAgentFinalize(EVENT, TEST_PLUGIN_AGENT_CTX)).resolves.toEqual({
|
||||
action: "revise",
|
||||
reason: "malformed retry payload should not crash\n\nvalid retry still applies",
|
||||
retry: {
|
||||
instruction: "rerun the focused tests",
|
||||
idempotencyKey: "valid-retry",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("lets finalize override earlier revise decisions", async () => {
|
||||
const runner = createHookRunner(
|
||||
createMockPluginRegistry([
|
||||
|
||||
@@ -322,7 +322,7 @@ export function createHookRunner(
|
||||
const normalizeRetry = (
|
||||
retry: PluginHookBeforeAgentFinalizeResult["retry"] | undefined,
|
||||
): PluginHookBeforeAgentFinalizeResult["retry"] | undefined => {
|
||||
const instruction = retry?.instruction.trim();
|
||||
const instruction = typeof retry?.instruction === "string" ? retry.instruction.trim() : "";
|
||||
if (!instruction) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -115,6 +115,9 @@ function waitForTerminalEventHandlers(params: {
|
||||
}
|
||||
let timeout: NodeJS.Timeout | undefined;
|
||||
const settled = Promise.allSettled(pendingHandlers).then(() => "settled" as const);
|
||||
// Promise.race bounds the host wait; JavaScript cannot cancel the plugin
|
||||
// promises themselves, so timeout also marks the run expired to block late
|
||||
// run-context resurrection by handlers that eventually settle.
|
||||
const timedOut = new Promise<"timeout">((resolve) => {
|
||||
timeout = setTimeout(() => {
|
||||
markTerminalEventCleanupExpired(runId);
|
||||
|
||||
Reference in New Issue
Block a user