mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-09 15:59:30 +00:00
Fix silent context-engine maintenance task delivery status (#102147)
* Fix silent context maintenance task delivery status * refactor(context-engine): document maintenance delivery invariant * fix(context-engine): preserve visible maintenance flows * style(context-engine): format maintenance test import * test(context-engine): use direct maintenance task lookup --------- Co-authored-by: Sascha Kuhlmann <coolmanns@users.noreply.github.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
parent
3ebcfb8ee3
commit
13821c9d34
2 changed files with 50 additions and 46 deletions
|
|
@ -9,7 +9,7 @@ import {
|
|||
} from "../../process/command-queue.js";
|
||||
import * as commandQueueModule from "../../process/command-queue.js";
|
||||
import { createQueuedTaskRun as createQueuedTaskRunOrNull } from "../../tasks/task-executor.js";
|
||||
import { resetTaskFlowRegistryForTests } from "../../tasks/task-flow-registry.js";
|
||||
import { getTaskFlowById, resetTaskFlowRegistryForTests } from "../../tasks/task-flow-registry.js";
|
||||
import {
|
||||
getTaskById,
|
||||
listTasksForOwnerKey,
|
||||
|
|
@ -654,7 +654,7 @@ describe("runContextEngineMaintenance", () => {
|
|||
requesterSessionKey: sessionKey,
|
||||
taskKind: TURN_MAINTENANCE_TASK_KIND,
|
||||
notifyPolicy: "silent",
|
||||
deliveryStatus: "pending",
|
||||
deliveryStatus: "not_applicable",
|
||||
});
|
||||
|
||||
if (!releaseForeground) {
|
||||
|
|
@ -1494,6 +1494,21 @@ describe("runContextEngineMaintenance", () => {
|
|||
await waitForAssertion(() => expect(maintain).toHaveBeenCalledTimes(1));
|
||||
expect(sendMessageMock).not.toHaveBeenCalled();
|
||||
expect(peekSystemEvents(sessionKey)).toStrictEqual([]);
|
||||
|
||||
const tasks = listTasksForOwnerKey(sessionKey).filter(
|
||||
(task) => task.taskKind === TURN_MAINTENANCE_TASK_KIND,
|
||||
);
|
||||
expect(tasks).toHaveLength(1);
|
||||
await waitForAssertion(() =>
|
||||
expect(getTaskById(tasks[0].taskId)?.status).toBe("succeeded"),
|
||||
);
|
||||
const task = requireRecord(getTaskById(tasks[0].taskId), "maintenance task");
|
||||
expectRecordFields(task, {
|
||||
status: "succeeded",
|
||||
notifyPolicy: "silent",
|
||||
deliveryStatus: "not_applicable",
|
||||
});
|
||||
expect(task.parentFlowId).toBeUndefined();
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
|
|
@ -1552,6 +1567,14 @@ describe("runContextEngineMaintenance", () => {
|
|||
"Background task update: Context engine turn maintenance.",
|
||||
),
|
||||
);
|
||||
const task = listTasksForOwnerKey(sessionKey).find(
|
||||
(candidate) => candidate.taskKind === TURN_MAINTENANCE_TASK_KIND,
|
||||
);
|
||||
const parentFlowId = task?.parentFlowId;
|
||||
if (!parentFlowId) {
|
||||
throw new Error("Expected visible maintenance to have a task flow");
|
||||
}
|
||||
expect(getTaskFlowById(parentFlowId)?.status).toBe("running");
|
||||
|
||||
if (!releaseMaintenance) {
|
||||
throw new Error("Expected maintenance release callback to be initialized");
|
||||
|
|
@ -1563,6 +1586,7 @@ describe("runContextEngineMaintenance", () => {
|
|||
"Background task done: Context engine turn maintenance",
|
||||
),
|
||||
);
|
||||
expect(getTaskFlowById(parentFlowId)?.status).toBe("succeeded");
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
|
|
@ -1609,6 +1633,14 @@ describe("runContextEngineMaintenance", () => {
|
|||
"Background task failed: Context engine turn maintenance",
|
||||
),
|
||||
);
|
||||
const task = listTasksForOwnerKey(sessionKey).find(
|
||||
(candidate) => candidate.taskKind === TURN_MAINTENANCE_TASK_KIND,
|
||||
);
|
||||
const parentFlowId = task?.parentFlowId;
|
||||
if (!parentFlowId) {
|
||||
throw new Error("Expected failed maintenance to have a task flow");
|
||||
}
|
||||
expect(getTaskFlowById(parentFlowId)?.status).toBe("failed");
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import {
|
|||
createQueuedTaskRun,
|
||||
failTaskRunByRunId,
|
||||
recordTaskRunProgressByRunId,
|
||||
setDetachedTaskDeliveryStatusByRunId,
|
||||
startTaskRunByRunId,
|
||||
} from "../../tasks/detached-task-runtime.js";
|
||||
import {
|
||||
|
|
@ -231,11 +230,15 @@ function markDeferredTurnMaintenanceTaskScheduleFailure(params: {
|
|||
});
|
||||
}
|
||||
|
||||
function buildTurnMaintenanceTaskDescriptor(params: { sessionKey: string }) {
|
||||
const runId = `turn-maint:${params.sessionKey}:${Date.now().toString(36)}:${randomUUID().slice(
|
||||
0,
|
||||
8,
|
||||
)}`;
|
||||
function buildTurnMaintenanceTaskDescriptor(params: {
|
||||
sessionKey: string;
|
||||
runId?: string;
|
||||
notifyPolicy?: "silent" | "done_only" | "state_changes";
|
||||
deliveryStatus?: "not_applicable" | "pending";
|
||||
}) {
|
||||
const runId =
|
||||
params.runId ??
|
||||
`turn-maint:${params.sessionKey}:${Date.now().toString(36)}:${randomUUID().slice(0, 8)}`;
|
||||
return createQueuedTaskRun({
|
||||
runtime: "acp",
|
||||
taskKind: TURN_MAINTENANCE_TASK_KIND,
|
||||
|
|
@ -246,8 +249,10 @@ function buildTurnMaintenanceTaskDescriptor(params: { sessionKey: string }) {
|
|||
runId,
|
||||
label: TURN_MAINTENANCE_TASK_LABEL,
|
||||
task: TURN_MAINTENANCE_TASK_TASK,
|
||||
notifyPolicy: "silent",
|
||||
deliveryStatus: "pending",
|
||||
notifyPolicy: params.notifyPolicy ?? "silent",
|
||||
// Fast maintenance stays silent and must not create a one-task flow.
|
||||
// Long-running and failed workers promote it to pending before notifying.
|
||||
deliveryStatus: params.deliveryStatus ?? "not_applicable",
|
||||
preferMetadata: true,
|
||||
});
|
||||
}
|
||||
|
|
@ -257,45 +262,12 @@ function promoteTurnMaintenanceTaskVisibility(params: {
|
|||
runId: string;
|
||||
notifyPolicy: "done_only" | "state_changes";
|
||||
}) {
|
||||
const task = findTaskByRunIdForOwner({
|
||||
runId: params.runId,
|
||||
callerOwnerKey: params.sessionKey,
|
||||
});
|
||||
if (!task) {
|
||||
return createQueuedTaskRun({
|
||||
runtime: "acp",
|
||||
taskKind: TURN_MAINTENANCE_TASK_KIND,
|
||||
sourceId: TURN_MAINTENANCE_TASK_KIND,
|
||||
requesterSessionKey: params.sessionKey,
|
||||
ownerKey: params.sessionKey,
|
||||
scopeKind: "session",
|
||||
runId: params.runId,
|
||||
label: TURN_MAINTENANCE_TASK_LABEL,
|
||||
task: TURN_MAINTENANCE_TASK_TASK,
|
||||
notifyPolicy: params.notifyPolicy,
|
||||
deliveryStatus: "pending",
|
||||
preferMetadata: true,
|
||||
});
|
||||
}
|
||||
setDetachedTaskDeliveryStatusByRunId({
|
||||
runId: params.runId,
|
||||
runtime: "acp",
|
||||
return buildTurnMaintenanceTaskDescriptor({
|
||||
sessionKey: params.sessionKey,
|
||||
runId: params.runId,
|
||||
notifyPolicy: params.notifyPolicy,
|
||||
deliveryStatus: "pending",
|
||||
});
|
||||
if (task.notifyPolicy !== params.notifyPolicy) {
|
||||
updateTaskNotifyPolicyForOwner({
|
||||
taskId: task.taskId,
|
||||
callerOwnerKey: params.sessionKey,
|
||||
notifyPolicy: params.notifyPolicy,
|
||||
});
|
||||
}
|
||||
return (
|
||||
findTaskByRunIdForOwner({
|
||||
runId: params.runId,
|
||||
callerOwnerKey: params.sessionKey,
|
||||
}) ?? task
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue