Environment
- SDK version: 0.1.6
- Python version: 3.13.9
- OS / platform: Linux x86_64
- Install method:
pip install google-antigravity (local connection / bundled localharness, Vertex backend, gemini-3.5-flash)
Description
Topology: a parent fans out sub-agents (invoke_subagent, built-in self), then processes all their results and calls finish. To wait for the sub-agents, the parent goes idle and is re-woken by their completion messages.
Bug: the run ends the instant the last sub-agent goes idle — even though the parent has already been re-woken and is actively running (mid tool-call, about to finish). The parent's in-flight request is cancelled (context canceled), so it never processes the results; for structured runs structured_output() returns None.
Cause (google/antigravity/connections/local/event_processor.py): parent_idle is set True on the parent's first STATE_IDLE and never reset to False when the parent goes STATE_RUNNING again — the STATE_RUNNING handler only touches active_subagent_ids, with no branch for the main trajectory:
if tsu.state == STATE_RUNNING:
if is_subagent:
self.active_subagent_ids.add(tsu.trajectory_id)
# no else: parent_idle stays latched True
elif tsu.state == STATE_IDLE:
if is_subagent:
self.active_subagent_ids.discard(tsu.trajectory_id)
else:
self.parent_idle = True
if self.parent_idle and not self.active_subagent_ids: # fires with a STALE parent_idle
self.is_idle.set(); await self.step_queue.put(IDLE_SENTINEL)
So a stale parent_idle == True plus an emptied active_subagent_ids sets is_idle and enqueues IDLE_SENTINEL; local_connection.receive_steps() returns; the async with AntigravityAgent(...) block exits and cancels the parent's in-flight request.
Steps to Reproduce
- Create an agent with
enable_subagents=True and a structured-output schema (response_schema).
- Give the parent a task that fans out ≥2 async sub-agents in one turn (
invoke_subagent, self, Workspace: inherit), then awaits their results (each sub-agent does non-trivial work, writes a file, send_messages the parent — so the parent goes idle and is re-woken).
- Run via
chat() → structured_output().
Reliably reproduces when sub-agent work takes long enough that the last sub-agent finishes while the parent is between/inside turns.
Expected Behavior
The run stays alive while the parent is STATE_RUNNING. After the last sub-agent finishes and the parent is re-woken, the parent assembles its answer and calls finish; structured_output() returns the result.
Actual Behavior
The moment the last sub-agent goes STATE_IDLE, the stale parent_idle == True + empty active_subagent_ids ends the step stream; the session tears down and cancels the parent's in-flight streamGenerateContent; structured_output() returns None. Connection log:
RAW WS MSG {"trajectoryStateUpdate":{"trajectoryId":"<subagent>","state":"STATE_IDLE"}}
INFO Stopping Agent session agent.py:159
INFO harness stderr: model response error: doRequest: error sending request:
Post ".../gemini-3.5-flash:streamGenerateContent?alt=sse": context canceled
Additional Context
Proposed fix — clear parent_idle when the main trajectory runs, symmetric to the STATE_IDLE handler:
if tsu.state == STATE_RUNNING:
if is_subagent:
self.active_subagent_ids.add(tsu.trajectory_id)
+ else:
+ self.parent_idle = False
Environment
pip install google-antigravity(local connection / bundledlocalharness, Vertex backend,gemini-3.5-flash)Description
Topology: a parent fans out sub-agents (
invoke_subagent, built-inself), then processes all their results and callsfinish. To wait for the sub-agents, the parent goes idle and is re-woken by their completion messages.Bug: the run ends the instant the last sub-agent goes idle — even though the parent has already been re-woken and is actively running (mid tool-call, about to
finish). The parent's in-flight request is cancelled (context canceled), so it never processes the results; for structured runsstructured_output()returnsNone.Cause (
google/antigravity/connections/local/event_processor.py):parent_idleis setTrueon the parent's firstSTATE_IDLEand never reset toFalsewhen the parent goesSTATE_RUNNINGagain — theSTATE_RUNNINGhandler only touchesactive_subagent_ids, with no branch for the main trajectory:So a stale
parent_idle == Trueplus an emptiedactive_subagent_idssetsis_idleand enqueuesIDLE_SENTINEL;local_connection.receive_steps()returns; theasync with AntigravityAgent(...)block exits and cancels the parent's in-flight request.Steps to Reproduce
enable_subagents=Trueand a structured-output schema (response_schema).invoke_subagent,self,Workspace: inherit), then awaits their results (each sub-agent does non-trivial work, writes a file,send_messages the parent — so the parent goes idle and is re-woken).chat()→structured_output().Reliably reproduces when sub-agent work takes long enough that the last sub-agent finishes while the parent is between/inside turns.
Expected Behavior
The run stays alive while the parent is
STATE_RUNNING. After the last sub-agent finishes and the parent is re-woken, the parent assembles its answer and callsfinish;structured_output()returns the result.Actual Behavior
The moment the last sub-agent goes
STATE_IDLE, the staleparent_idle == True+ emptyactive_subagent_idsends the step stream; the session tears down and cancels the parent's in-flightstreamGenerateContent;structured_output()returnsNone. Connection log:Additional Context
Proposed fix — clear
parent_idlewhen the main trajectory runs, symmetric to theSTATE_IDLEhandler:if tsu.state == STATE_RUNNING: if is_subagent: self.active_subagent_ids.add(tsu.trajectory_id) + else: + self.parent_idle = False