mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-12 22:22:54 +00:00
fix(cron): cancel timed-out runs before side effects (openclaw#22411) thanks @Takhoffman
Verified: - pnpm check - pnpm vitest run src/memory/qmd-manager.test.ts src/cron/service.issue-regressions.test.ts src/cron/isolated-agent.delivers-response-has-heartbeat-ok-but-includes.test.ts --maxWorkers=1 Co-authored-by: Takhoffman <781889+Takhoffman@users.noreply.github.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
@@ -156,10 +156,19 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
job: CronJob;
|
||||
message: string;
|
||||
abortSignal?: AbortSignal;
|
||||
signal?: AbortSignal;
|
||||
sessionKey: string;
|
||||
agentId?: string;
|
||||
lane?: string;
|
||||
}): Promise<RunCronAgentTurnResult> {
|
||||
const abortSignal = params.abortSignal ?? params.signal;
|
||||
const isAborted = () => abortSignal?.aborted === true;
|
||||
const abortReason = () => {
|
||||
const reason = abortSignal?.reason;
|
||||
return typeof reason === "string" && reason.trim()
|
||||
? reason.trim()
|
||||
: "cron: job execution timed out";
|
||||
};
|
||||
const isFastTestEnv = process.env.OPENCLAW_TEST_FAST === "1";
|
||||
const defaultAgentId = resolveDefaultAgentId(params.cfg);
|
||||
const requestedAgentId =
|
||||
@@ -473,8 +482,8 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
agentDir,
|
||||
fallbacksOverride: resolveAgentModelFallbacksOverride(params.cfg, agentId),
|
||||
run: (providerOverride, modelOverride) => {
|
||||
if (params.abortSignal?.aborted) {
|
||||
throw new Error("cron: isolated run aborted");
|
||||
if (abortSignal?.aborted) {
|
||||
throw new Error(abortReason());
|
||||
}
|
||||
if (isCliProvider(providerOverride, cfgWithAgentDefaults)) {
|
||||
const cliSessionId = getCliSessionId(cronSession.sessionEntry, providerOverride);
|
||||
@@ -517,7 +526,7 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
runId: cronSession.sessionEntry.sessionId,
|
||||
requireExplicitMessageTarget: true,
|
||||
disableMessageTool: deliveryRequested,
|
||||
abortSignal: params.abortSignal,
|
||||
abortSignal,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -529,6 +538,10 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
return withRunSession({ status: "error", error: String(err) });
|
||||
}
|
||||
|
||||
if (isAborted()) {
|
||||
return withRunSession({ status: "error", error: abortReason() });
|
||||
}
|
||||
|
||||
const payloads = runResult.payloads ?? [];
|
||||
|
||||
// Update token+model fields in the session store.
|
||||
@@ -584,6 +597,10 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
}
|
||||
await persistSessionEntry();
|
||||
}
|
||||
|
||||
if (isAborted()) {
|
||||
return withRunSession({ status: "error", error: abortReason(), ...telemetry });
|
||||
}
|
||||
const firstText = payloads[0]?.text ?? "";
|
||||
let summary = pickSummaryFromPayloads(payloads) ?? pickSummaryFromOutput(firstText);
|
||||
let outputText = pickLastNonEmptyTextFromPayloads(payloads);
|
||||
@@ -672,6 +689,9 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
? [{ text: synthesizedText }]
|
||||
: [];
|
||||
if (payloadsForDelivery.length > 0) {
|
||||
if (isAborted()) {
|
||||
return withRunSession({ status: "error", error: abortReason(), ...telemetry });
|
||||
}
|
||||
const deliveryResults = await deliverOutboundPayloads({
|
||||
cfg: cfgWithAgentDefaults,
|
||||
channel: resolvedDelivery.channel,
|
||||
@@ -683,6 +703,7 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
identity,
|
||||
bestEffort: deliveryBestEffort,
|
||||
deps: createOutboundSendDeps(params.deps),
|
||||
abortSignal,
|
||||
});
|
||||
delivered = deliveryResults.length > 0;
|
||||
}
|
||||
@@ -765,6 +786,9 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
return withRunSession({ status: "ok", summary, outputText, delivered: true, ...telemetry });
|
||||
}
|
||||
try {
|
||||
if (isAborted()) {
|
||||
return withRunSession({ status: "error", error: abortReason(), ...telemetry });
|
||||
}
|
||||
const didAnnounce = await runSubagentAnnounceFlow({
|
||||
childSessionKey: agentSessionKey,
|
||||
childRunId: `${params.job.id}:${runSessionId}`,
|
||||
@@ -785,6 +809,7 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
endedAt: runEndedAt,
|
||||
outcome: { status: "ok" },
|
||||
announceType: "cron job",
|
||||
signal: abortSignal,
|
||||
});
|
||||
if (didAnnounce) {
|
||||
delivered = true;
|
||||
|
||||
Reference in New Issue
Block a user