feat(delegate): add background task lifecycle - #4503
Conversation
Co-authored-by: openhands <openhands@all-hands.dev>
|
📁 PR Artifacts Notice This PR contains a |
|
Maintainer action needed to unblock the remaining gates:
The PR description contains the completed local test, smoke, pre-commit, and API-compatibility evidence. |
Co-authored-by: openhands <openhands@all-hands.dev>
|
🚦 CI is currently failing on this PR's latest commit. Please fix the failing checks before OpenHands reviews it - this is re-checked automatically once you push a new commit. (A maintainer can also request This is an automated check - no AI was used to generate this comment. |
Co-authored-by: openhands <openhands@all-hands.dev>
|
@enyst, this PR has been substantially redesigned since my earlier CI-gate comment. The current implementation places background execution in the existing The public contract is:
|
|
🚦 CI is currently failing on this PR's latest commit. Please fix the failing checks before OpenHands reviews it - this is re-checked automatically once you push a new commit. (A maintainer can also request This is an automated check - no AI was used to generate this comment. |
HUMAN:
I designed and implemented process-local background task execution in the existing TaskToolSet/TaskManager, with stable task identities, an explicit queued/running/completed/error/cancelled state machine, synchronization scoped to the task manager and parent conversation, parallel execution of independent tasks, cooperative cancellation, bounded stop/close waiting without force-killing threads, exactly-once terminal settlement and usage accounting, and compatibility with the existing blocking path. I produced the self-contained design document and added deterministic concurrency, cancellation, cleanup, and accounting coverage. I personally ran and reviewed the 165 focused and related tests, scoped pre-commit checks, and the SDK API compatibility check documented below.
AGENT:
AI assistance was limited to targeted secondary review of lifecycle edge cases, tests, documentation, and organization of the verification evidence. I personally reviewed that feedback, made the architecture and implementation decisions, ran the acceptance commands, and verified the final behavior before submission.
Why
The original background attempt kept a separate lifecycle registry beside
DelegateExecutor. That duplicated task ownership and left the public API and existing task persistence paths inconsistent. This revision puts the lifecycle on the existingTaskToolSetowner, while keeping blocking task execution fully compatible by default.Summary
TaskAction(run_in_background=True).task_outputandtask_stoptools backed by the same parent-scopedTaskManager.queued -> running -> completed | error | cancelledtransitions with stable task IDs.LocalConversation.arun()and cooperativeinterrupt()cancellation; never force-kill Python threads.Task IDs and live worker state are process-local. After a process restart, an old ID is reported as unknown even when persisted conversation files remain.
API Surface
TaskAction(run_in_background=True)returns aTaskObservationwith the stable task ID and an initialqueuedorrunningstatus.TaskOutputAction(task_id, block=False, timeout=30.0)is read-only. Withblock=True, it waits for settlement, stop, or manager close, subject to a finite0-3600second timeout.TaskStopAction(task_id)requestsLocalConversation.interrupt(), waits up to the bounded cleanup deadline, and reports the resulting status.Issue Number
Addresses #2047 and unblocks the background work tracked by #2186.
How to Test
Result:
165 passed, 71 warnings.Scoped pre-commit checks for the changed SDK files passed: Ruff format/check, pycodestyle, Pyright, import dependency rules, and tool registration.
Design Doc
https://htmlpreview.github.io/?https://github.com/KirschBluteX/software-agent-sdk/blob/feat/background-delegation-2047/.pr/design.html
Type
Notes
TaskManagerand parent conversation; persisted conversations do not imply restorable worker threads or task IDs.