Tasks: route one-task emergence through parent flows (#57874)

This commit is contained in:
Mariano
2026-03-30 20:25:01 +02:00
committed by GitHub
parent 7590c22db7
commit 9d9cf0d8ff
6 changed files with 535 additions and 32 deletions

View File

@@ -1,7 +1,10 @@
import type { OpenClawConfig } from "../config/config.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { createFlowForTask, deleteFlowRecordById } from "./flow-registry.js";
import {
cancelTaskById,
createTaskRecord,
linkTaskToFlowById,
markTaskLostById,
markTaskRunningByRunId,
markTaskTerminalByRunId,
@@ -18,6 +21,53 @@ import type {
TaskTerminalOutcome,
} from "./task-registry.types.js";
const log = createSubsystemLogger("tasks/executor");
function isOneTaskFlowEligible(task: TaskRecord): boolean {
if (task.parentFlowId?.trim() || !task.requesterSessionKey.trim()) {
return false;
}
if (task.deliveryStatus === "not_applicable") {
return false;
}
return task.runtime === "acp" || task.runtime === "subagent";
}
function ensureSingleTaskFlow(params: {
task: TaskRecord;
requesterOrigin?: TaskDeliveryState["requesterOrigin"];
}): TaskRecord {
if (!isOneTaskFlowEligible(params.task)) {
return params.task;
}
try {
const flow = createFlowForTask({
task: params.task,
requesterOrigin: params.requesterOrigin,
});
const linked = linkTaskToFlowById({
taskId: params.task.taskId,
flowId: flow.flowId,
});
if (!linked) {
deleteFlowRecordById(flow.flowId);
return params.task;
}
if (linked.parentFlowId !== flow.flowId) {
deleteFlowRecordById(flow.flowId);
return linked;
}
return linked;
} catch (error) {
log.warn("Failed to create one-task flow for detached run", {
taskId: params.task.taskId,
runId: params.task.runId,
error,
});
return params.task;
}
}
export function createQueuedTaskRun(params: {
runtime: TaskRuntime;
sourceId?: string;
@@ -34,10 +84,14 @@ export function createQueuedTaskRun(params: {
notifyPolicy?: TaskNotifyPolicy;
deliveryStatus?: TaskDeliveryStatus;
}): TaskRecord {
return createTaskRecord({
const task = createTaskRecord({
...params,
status: "queued",
});
return ensureSingleTaskFlow({
task,
requesterOrigin: params.requesterOrigin,
});
}
export function createRunningTaskRun(params: {
@@ -59,10 +113,14 @@ export function createRunningTaskRun(params: {
lastEventAt?: number;
progressSummary?: string | null;
}): TaskRecord {
return createTaskRecord({
const task = createTaskRecord({
...params,
status: "running",
});
return ensureSingleTaskFlow({
task,
requesterOrigin: params.requesterOrigin,
});
}
export function startTaskRunByRunId(params: {