fix: reject inline tasks during agent handoff - #7268
chenghao-mou wants to merge 4 commits into
Conversation
Reject inline tasks from an outgoing activity once handoff starts. This breaks the circular wait between activity shutdown and a tool awaiting the transition lock, while preserving normal inline-task pause and resume. Co-authored-by: Dan Tran <danganhtran@me.com>
There was a problem hiding this comment.
🔴 Public drain deadlocks inline tasks
When AgentSession.drain() overlaps a tool awaiting an AgentTask, drain admits that inline task. The task waits for the activity lock while drain waits for its scheduling task, so both hang.
Learn more
AgentSession.drain() calls this method directly without going through _update_activity, so no other path sets _new_turns_blocked. An admitted inline AgentTask calls _update_activity(..., previous_activity="pause"), which eventually needs this activity's lock. The ongoing drain owns that lock and waits for _scheduling_atask, which contains the tool awaiting the inline task. Neither operation can finish.
Example: A non-cancellable tool pauses before await InlineTask(). Another coroutine starts session.drain(), then releases the tool. The inline task passes _inline_task_slot, waits to pause the locked activity, and the drain waits for that same tool to finish.
Recommended fix: Preserve admission blocking for a successful public drain, but roll it back if the drain is cancelled before scheduling pauses. Keep handoff blocking synchronous in _update_activity and avoid clearing a flag established by another concurrent transition.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
The agent_activity.py:2067 permits this because the excluded tool no longer counts as pending work.
The handoff case has an additional dependency: after drain, activity.aclose() waits for the tool executor while the handoff still holds the session’s _activity_lock. That prevents the inline task’s _update_activity() from proceeding. Public drain does neither.
An outgoing tool can deadlock handoff by awaiting an
AgentTask. Reject that task with a transitionToolErrorfrom handoff request through drain.Reproduces @dtran26's report in agents-js#2483. The Python fix was developed independently; the similar JS fix was discovered afterward.
147 focused tests and core type checks pass. Full plugin type checks are blocked by environment errors.
Addresses AGT-3502.
Initial prompt and agent context
Model: GPT-6
Essential follow-up instructions: