[FEATURE] Expose background tasks (and tools-called-this-turn) to hooks — re-raise of #23386 with agent-teams use cases

Resolved 💬 2 comments Opened May 12, 2026 by Butanium Closed Jun 11, 2026

Summary

Re-raising #23386 (auto-closed for inactivity, then locked, no maintainer engagement). The original ask — make running background tasks visible to hooks via input JSON — is still valid, and the agent-teams primitive landed in the interim has made it strictly more useful. I'd also push the ask one step broader: expose agent execution state to hooks, of which background_tasks is one slice and "tools called this turn" is another (motivated below).

Original use cases (from #23386, still apply)

  1. Prevent duplicate work — a PreToolUse hook can block starting a second build/test run if one is already in progress.
  2. Resource management — limit concurrent background tasks to avoid overwhelming the system.
  3. Stop-hook coordination — check if background work is still pending before allowing the agent to finish.
  4. Debugging / observability — log or display what's currently running.

New: agent-teams use cases

The TeammateIdle hook exists but is partially blind to the state of the teammate it's gating.

  1. TeammateIdle gate on in-flight background work. A teammate that still has a long-running Bash run_in_background:true or background Agent shouldn't be allowed to idle yet, but the hook can't see what's still running. Without background-task visibility, the hook either over-blocks (forces wake-ups just to "check on something") or under-blocks (lets the teammate idle while a build/eval/job is still in flight). Either pattern degrades how the team-lead reasons about teammate state.
  1. Catch teammates that finished without calling SendMessage. A teammate ending a turn without SendMessage AND with no background tasks pending is almost certainly stuck — they did the work but never told the lead. A TeammateIdle hook with visibility into (a) tools called this turn and (b) running background tasks could implement:

> "no SendMessage called this turn AND no background work pending → block idle, prompt the teammate to send a message to the lead before stopping."

This is a real recurring failure mode that the lead currently has to detect after the fact (or never).

This is the case that motivates the broader framing: background_tasks alone isn't enough. Tools-called-this-turn is the adjacent field that closes the loop.

  1. Lead-side stall detection. A Stop hook on the lead could check whether any teammate has background work pending before allowing the lead's turn to end. Less critical, same pattern.

Proposed input shape

Same shape as #23386 proposed, plus a sibling field for the per-turn tool calls:

{
  "session_id": "abc123",
  "hook_event_name": "TeammateIdle",
  "teammate_name": "researcher",
  "team_name": "infra",
  "background_tasks": [
    {
      "task_id": "task-xyz",
      "tool_name": "Bash",
      "started_at": "2026-05-12T10:30:00Z",
      "description": "Running test suite"
    },
    {
      "task_id": "agent-abc",
      "tool_name": "Agent",
      "subagent_type": "Explore",
      "started_at": "2026-05-12T10:31:00Z",
      "description": "Exploring codebase"
    }
  ],
  "tools_called_this_turn": [
    {"tool_name": "Read", "count": 4},
    {"tool_name": "Edit", "count": 1}
  ]
}

Exact shape is a strawman — what matters is exposing these two pieces of state.

Current workaround (still bad)

Per-session sidecar state files keyed off session_id work for background_tasks but require user code to mirror what the harness already tracks. For "tools called this turn" the workaround is re-parsing the session's JSONL transcript on every hook fire — expensive and brittle.

Related

  • #23386 — original request for background_tasks (auto-closed for inactivity, locked).
  • #4321 — Session-Scoped In-Memory State for Hooks (broader framing).
  • #50779 — agent-teams inbox delivery deferred until end_turn; the workarounds in the comments there would benefit from background-task visibility for similar reasons.

---

🤖 Generated with Claude Code

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗