Skip to content

fix(agents): refuse a second inline AgentTask on the same activity - #6860

Open
u9g wants to merge 9 commits into
mainfrom
jason/inline-agent-task-concurrency-guard
Open

fix(agents): refuse a second inline AgentTask on the same activity#6860
u9g wants to merge 9 commits into
mainfrom
jason/inline-agent-task-concurrency-guard

Conversation

@u9g

@u9g u9g commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

An LLM turn with parallel tool calls can await an AgentTask from more than one call; each pauses the same activity, only the last handoff survives, and the losers are never active again so nothing completes them — their function calls never return and the session hangs until close times out. AgentActivity now records the inline task that paused it, and a second one awaited while the first is still in flight raises ToolError, which is the rule the returned-AgentTask path already enforces via expected to receive only one AgentTask from the tool executions. The replaced TODO asked for a global lock, but one held across the task's lifetime would deadlock the supported nesting pattern, where an outer task holds it while awaiting an inner one whose own tool needs it to progress.

u9g added 2 commits August 14, 2026 15:38
…nish callback

Hoists the context-var reads and the already-interrupted check above the
_handle_task_done definition in AgentTask.__await_impl, so every path that
rejects the await outright runs before the callback is registered.

The callback exists to complete the task when its asyncio.Task finishes first.
An early raise was tripping it, reporting a task that never started as having
finished prematurely.
An LLM turn with parallel tool calls can await an AgentTask from each call.
Every one of them pauses the same activity and hands off, but only the last
handoff survives: the losers are never active again, so nothing completes them.
Each stays parked on its result, its function call never returns, the speech
never finishes, and the session hangs until close times out - reported by the
caller as the agent going silent.

The activity now records the inline task that paused it, and a second one
awaited while it is still in flight raises a ToolError instead. The returned
AgentTask path already refuses a turn that yields more than one; this is the
same rule for the awaited path. A nested AgentTask pauses a different activity,
so the existing nesting flow is untouched.

Replaces the TODO asking for a global lock. A lock covering the task's whole
lifetime would deadlock that nesting: an outer task holds it while awaiting an
inner one, whose own tool needs it to make progress.
@u9g
u9g requested a review from a team as a code owner August 14, 2026 19:42
devin-ai-integration[bot]

This comment was marked as resolved.

u9g added 7 commits August 14, 2026 15:48
agent_activity imports Agent at module scope, so hoisting this one fails on
either entry point with a partially-initialized-module ImportError.
…e mode

Both comments around the one-paused-inline-task rule spent most of their lines
tracing what goes wrong when it is violated. Keeps the invariant and the
placement constraints, drops the walkthrough.
The reason the registration sits below the raising checks is in the commit that
moved it.
The field declaration already states the lifetime this repeated.
CancelledError derives from BaseException, so an except Exception handler let a
cancellation during the pause escape with the inline-task claim still held. The
activity then refuses every later inline task for the rest of the session.

Reachable through a forced interrupt, which bypasses the disallowed
interruptions the claim is held under and cancels the tool task.

The same handler's pre-existing __inactive_ev release was escaping too.
The check and its error message carry the rule.
devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration Bot 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.

Devin Review found 1 new potential issue.

View 2 additional findings in Devin Review.

Open in Devin Review

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.

1 participant