Skip to content

feat(shell): add wait_background_job tool#3463

Merged
Sayt-0 merged 1 commit into
docker:mainfrom
simonferquel-clanker:feat/wait-background-job
Jul 4, 2026
Merged

feat(shell): add wait_background_job tool#3463
Sayt-0 merged 1 commit into
docker:mainfrom
simonferquel-clanker:feat/wait-background-job

Conversation

@simonferquel-clanker

Copy link
Copy Markdown
Contributor

🤖 Automated implementer agentthis comment was posted by the implementer bot from Docker Agentic Platform, not by a human developer

Adds a wait_background_job tool to the shell toolset that blocks until a background job finishes and returns its exit code and captured output.

Previously, agents had to poll view_background_job in a loop to know when a background job completed. The new tool blocks on a done chan struct{} closed by monitorJob, eliminating polling entirely. An optional timeout parameter (default 60 s) caps the wait; the job keeps running if the timeout fires and the tool returns the current output with a notice.

Key changes:

  • done chan struct{} on backgroundJob, closed by monitorJob via a deferred close (LIFO: Unlock before close, so callers see fully written state)
  • Extract renderBackgroundJob() helper; refactor ViewBackgroundJob to use it; fix pre-existing issue: stopped jobs no longer show Exit Code: 0
  • WaitBackgroundJob handler with ReadOnlyHint: true; selects on job.done / timer.C / ctx.Done
  • 7 tests: completed, failed-exit, already-completed, unknown-id, timeout, context-cancelled, stopped-then-wait
  • Docs updated: six tools, wait_background_job parameters table

Closes #3462

Add a wait_background_job tool to the shell toolset that blocks until a
background job finishes and returns its exit code and captured output.

Previously agents had to poll view_background_job in a loop. The new
tool blocks on a done channel closed by monitorJob, avoiding polling
entirely. An optional timeout parameter (default 60 s) caps the wait;
the job keeps running if the timeout fires.

Changes:
- Add done chan struct{} to backgroundJob, closed by monitorJob via a
  deferred close (LIFO: Unlock fires before close, ensuring callers see
  fully written state)
- Extract renderBackgroundJob() helper; refactor ViewBackgroundJob to
  use it (no behavior change). Fix pre-existing issue: stopped jobs no
  longer incorrectly show Exit Code: 0
- Add WaitBackgroundJob handler with ReadOnlyHint: true; select on
  job.done / timer.C / ctx.Done
- Register wait_background_job in Tools() and Instructions()
- Update docs: six tools, wait_background_job parameters table
- Add 7 tests: completed, failed-exit, already-completed, unknown-id,
  timeout, context-cancelled, and stopped-then-wait
- Update teamloader readonly integration tests to include
  wait_background_job in the read-only tool set

Closes docker#3462
@simonferquel-clanker simonferquel-clanker requested a review from a team as a code owner July 3, 2026 22:51

@docker-agent docker-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟢 APPROVE

The wait_background_job implementation is correct and well-structured. Key design points verified:

  • Defer ordering is correct: defer close(job.done) is registered first, defer job.outputMu.Unlock() second — LIFO ensures the mutex is released before the channel is closed, so WaitBackgroundJob readers always see fully-committed state.
  • Stopped-job path: monitorJob acquires the lock, detects statusStopped, returns early; both defers still fire in correct order. statusStopped is present in statusStrings so the map lookup in WaitBackgroundJob is always valid.
  • No double-close risk: done is only closed inside monitorJob, which runs exactly once per job.
  • Timeout path: renderBackgroundJob is safely callable while the job is running (uses outputMu.RLock).
  • 7 tests cover: completed, failed-exit, already-completed, unknown-id, timeout, context-cancelled, and stopped-then-wait.

No bugs found in the changes introduced by this PR.

@aheritier aheritier added area/docs Documentation changes area/tools For features/issues/fixes related to the usage of built-in and MCP tools kind/feat PR adds a new feature (maps to feat:). Use on PRs only. labels Jul 3, 2026
@Sayt-0 Sayt-0 merged commit 3be8353 into docker:main Jul 4, 2026
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docs Documentation changes area/tools For features/issues/fixes related to the usage of built-in and MCP tools kind/feat PR adds a new feature (maps to feat:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shell background job tool needs a companion wait_background_job tool to wait on completion

4 participants