Skip to content

fix(harness): stop cancelled async subagents - #2826

Open
guslegend0510 wants to merge 11 commits into
agentscope-ai:mainfrom
guslegend0510:codex/fix-2789-subagent-cancellation
Open

fix(harness): stop cancelled async subagents#2826
guslegend0510 wants to merge 11 commits into
agentscope-ai:mainfrom
guslegend0510:codex/fix-2789-subagent-cancellation

Conversation

@guslegend0510

Copy link
Copy Markdown
Contributor

AgentScope-Java Version

2.0.3-SNAPSHOT

Description

Fixes #2789.

Background

Calling task_cancel updated the task status to CANCELLED, but did not stop an already-running local subagent.

The task repository only cancelled the wrapping CompletableFuture. Since CompletableFuture.cancel(true) does not interrupt an executing supplier, the subagent could continue making model and tool calls after cancellation.

Timeout-promoted tasks had a similar issue because the original Reactor Disposable was not retained by the adopted background task.

Changes

  • Add optional cancellation hooks to:
    • LocalTaskRunSpec
    • AdoptedTaskRunSpec
  • Keep the existing single-argument constructors for backward compatibility.
  • Make BackgroundTask cancellation atomic and idempotent.
  • Track and cancel the real executor Future<?>.
  • Register task handles before executor submission so queued tasks can be cancelled before starting.
  • Preserve and dispose the original Reactor subscription for timeout-promoted tasks.
  • Persist cancelRequested=true and CANCELLED before invoking local cancellation handles.
  • Prevent cancelled tasks from being overwritten by late COMPLETED or FAILED results.
  • Suppress completion callbacks, inbox reminders, and wakeups for explicitly cancelled tasks.
  • Apply the same lifecycle handling to both:
    • WorkspaceTaskRepository
    • ControlPlaneTaskRepository
  • Handle the control-plane /cancel 404 race without skipping local cancellation.
  • Let the creating node observe cross-node cancellation through the existing heartbeat mechanism.
  • Use the exact child user/session when interrupting synchronous subagent executions.
  • Avoid session-wide interruption for background tasks so cancelling one task does not affect another task sharing the same persistent child.
  • Update the English and Chinese subagent documentation with same-node and cross-node cancellation semantics.

Remote Agent Protocol behavior remains unchanged apart from cancellation ordering and late-result protection.

Cancellation semantics

  • Same-node cancellation stops the exact local task immediately.
  • Cross-node cancellation is persisted first and picked up by the creating node's heartbeat.
  • The current default heartbeat interval is 30 seconds, so cross-node cancellation may take up to approximately one heartbeat interval.

Validation

  • Core: 2,294 tests passed, 9 skipped.
  • Harness: 841 tests passed, 3 skipped.
  • Aistio: 53 tests passed.
  • Final cancellation-specific regression suite: 41 tests passed.
  • mvn spotless:check passed for the affected modules.
  • git diff --check passed.

Regression coverage includes:

  • Idempotent cancellation.
  • Cancel-versus-completion races.
  • Cancellation hook failures.
  • Delayed executor Future registration.
  • Queued task cancellation before supplier execution.
  • Running task interruption.
  • Late completion suppression.
  • Timeout promotion subscription disposal.
  • Multiple-task isolation on a shared child.
  • Cross-repository heartbeat cancellation.
  • Control-plane cancellation 404 races.
  • Suppression of completion callbacks, inbox reminders, and wakeups.

Checklist

  • Code has been formatted with mvn spotless:apply
  • All relevant tests are passing
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated
  • Code is ready for review

@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]:TaskRepository.cancelTask 无法停止正在执行的异步 subagent —— cancelRequested 在 agent 执行循环内没有检查点

2 participants