fix(runtime): cancel en cascade des tasks filles — stop agent / cancel parent (#200, QA verte)
Cancel transitif, idempotent et ownership-aware sur le graphe parent→enfants des background tasks: - domain/background_task + ports: modèle parent/enfant (parent_task_id, rejet du self-parent), index children_by_parent, traversal des descendants en largeur. - application/background + infrastructure/store: cascade cancel (annule les descendants running/open, laisse les terminaux), idempotente face aux double-cancel et ordres de terminaison non déterministes; respect de l'ownership (parent_task_link). - orchestrator/service: stop agent → cascade cancel des tasks lancées par cet agent (relatesTo #196); cancel task parent → cascade de ses sous-tasks (dependsOn #199). Refactor unifiant le chemin de cancel, sans sémantique #196/#199 regreffée (tests hérités verts). - frontend: projection parentTaskId (workstate normalization/domain/services). Tests QA verts: domain background_task, application background_task_cancel (cascades_background_task_subtree, cascades_to_running_child, cascades_to_open_descendants_and_leaves_terminal_child, parent_task_link_roundtrips_and_rejects_self_parent), orchestrator_service, workstate_actions, workstate.test.tsx.
This commit is contained in:
@ -113,10 +113,12 @@ function normalizeBackgroundTask(
|
||||
const conversationId = optionalString(
|
||||
task.conversationId ?? task.conversation_id,
|
||||
);
|
||||
const parentTaskId = optionalString(task.parentTaskId ?? task.parent_task_id);
|
||||
return {
|
||||
taskId: stringValue(task.taskId, `legacy-task-${index}`),
|
||||
ownerAgentId: stringValue(task.ownerAgentId, fallbackAgentId),
|
||||
projectId: stringValue(task.projectId),
|
||||
...(parentTaskId ? { parentTaskId } : {}),
|
||||
kind: stringValue(task.kind, "background"),
|
||||
status: normalizeBackgroundStatus(task.status ?? task.state),
|
||||
exitCode: nullableNumber(task.exitCode),
|
||||
|
||||
@ -611,6 +611,7 @@ export interface BackgroundCompletion {
|
||||
taskId: string;
|
||||
ownerAgentId: string;
|
||||
projectId: string;
|
||||
parentTaskId?: string;
|
||||
kind: string;
|
||||
status:
|
||||
| "running"
|
||||
|
||||
@ -141,6 +141,7 @@ export interface BackgroundTaskStatus {
|
||||
taskId: string;
|
||||
ownerAgentId: string;
|
||||
projectId: string;
|
||||
parentTaskId?: string;
|
||||
kind: string;
|
||||
status:
|
||||
| "pending"
|
||||
@ -447,6 +448,7 @@ function toBackgroundTaskStatus(task: BackgroundCompletion): BackgroundTaskStatu
|
||||
taskId: task.taskId,
|
||||
ownerAgentId: task.ownerAgentId,
|
||||
projectId: task.projectId,
|
||||
...(task.parentTaskId ? { parentTaskId: task.parentTaskId } : {}),
|
||||
kind: task.kind,
|
||||
status: task.status,
|
||||
exitCode: task.exitCode,
|
||||
|
||||
Reference in New Issue
Block a user