Repository navigation
fix(agent-status): an Antigravity subagent finishing no longer ends its parent's turn - #33645
Conversation
…ts parent's turn Antigravity runs invoke_subagent children inside the parent agy process, and their hooks fire with their own conversationId. The child's fully idle Stop was read as the pane's turn end, so automations completed (and closed the tab) while the parent was still waiting for its subagents. Remember the conversation that called invoke_subagent/send_message and drop other conversations' hooks on that pane until its own fully idle Stop. Fixes #17650
|
No actionable comments were generated in the recent review.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments: 1
src/shared/agent-hook-listener-antigravity.test.ts: 1
485-485:Trivial · Maintainability & Code Quality · Quick win Narrow the
#17650attribution or add Codex-specific coverage.This fixture covers Antigravity
invoke_subagentevents only. It does not establish that a scheduled Codex automation with nestedcodex execresumes the parent or captures the parent’s final response. Remove#17650from the fixture attribution unless the test also covers the linked Codex workflow.

Review info
-
Run configuration-
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
9cb7c41d-d855-4a3b-ac83-08595b11f875
Files selected for processing: 3-
src/shared/agent-hook-listener-antigravity.test.tssrc/shared/agent-hook-listener/listener-state.tssrc/shared/agent-hook-listener/providers/antigravity-events.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.
-
| (eventName === 'PreToolUse' || eventName === 'PostToolUse') && | ||
| isAntigravitySubagentTool(toolName) | ||
| ) { | ||
| state.antigravitySubagentParentByPaneKey.set(paneKey, conversationId) |
There was a problem hiding this comment.
Record the parent only after the completed-transcript check.
If an invoke_subagent PostToolUse arrives after the parent’s idle Stop, this line restores the parent mapping. Lines 45-51 then discard that bookkeeping event, but leave the mapping in place. A new conversation on the same pane is ignored until another idle Stop from the old parent or a cache clear. Move parent tracking below the completed-transcript check, and cover this event order in a regression test.
…a stuck subagent parent If agy exits mid-subagent there is no idle Stop, so the parent marker stayed and every hook from a relaunched agy in the same terminal was dropped. Subagent hooks never carry lastUserInput, so a foreign conversation with user input now replaces the parent. Also clear the marker on turn-cache and closed-tab cleanup.
Summary
When an Antigravity agent hands work to its built-in
invoke_subagentsubagents, Orca was treating the first subagent to finish as the end of the whole run. Automations marked the runcompleted, recorded the subagent's message as the output, and closed the tab (SIGTERM toagy) while the parent was still waiting for its subagents. With this change Orca ignores subagent hooks on that pane until the parent's own turn ends.Root cause
Antigravity runs subagents inside the parent
agyprocess, so they fire the same~/.gemini/config/hooks.jsonhooks as the parent, using their ownconversationId(and their ownbrain/<id>/…/transcript_full.jsonl).agy1.4.7 does not fill in theparentConversationId/rootConversationIdfields that exist in itsHookArgsCommonproto, so those can't be used to spot a subagent. Captured from a liveagy1.4.7 run (fake model endpoint, see below):normalizeAntigravityEventtreated anyfullyIdleStop as terminal, so the subagent's Stop set the pane todoneand read the subagent's transcript intolastAssistantMessage. The automation'stui-idlewait then completed. That matches what the reporter saw:close_tab, then SIGTERM, then acompletedrun whoseoutputSnapshotheld the subagent's report. #31780 can't catch this case because it relies on separate nested processes.Upstream reference (closed binary
agy1.4.7,strings): thehooks_pb.HookArgsCommonfieldsconversation_id,parent_conversation_id,root_conversation_id,caller_context;StopHookArgs.fully_idle; the bundled hooks doc ("fullyIdle: true if all background tasks are done"); and theinvoke_subagenttool schema (TypeName,Role,Prompt,Workspace).What changed
antigravity-events.ts: when a conversation callsinvoke_subagentorsend_message, Orca records it as the pane's subagent parent. Until that conversation's own fully idle Stop, hooks from any otherconversationIdthat has nolastUserInput(that is, from subagents) are dropped. A foreign conversation that carries user input replaces the parent. Subagents are created inside the parent'sPreToolUse, so the parent is always recorded before any subagent hook arrives.listener-state.ts: a new pane-scoped mapantigravitySubagentParentByPaneKey, cleared, moved, and reset alongside the existing Antigravity cache.Verification
agysupportsAGY_LLM_GATEWAY_URLwithAGY_LLM_GATEWAY_WIRE_PROTOCOL=openai. I pointed it at a local scripted fake/v1/chat/completionsserver (parent callsinvoke_subagent→ subagent replies after 12 s → parent writes its final report after 5 s), with an isolated HOME.agyin an Orca terminal against Orca's managed Antigravity hooks and subscribed toagentStatusByPaneKey:working→done"SUBAGENT_REPORT: translation done" (15.46 s) →working→done"PARENT_FINAL_REPORT…" (20.76 s)working→done"PARENT_FINAL_REPORT…" (20.93 s), with no earlydonenormalizeHookPayloadgives the same result: on main the subagent Stop isdonewith the subagent's message; on this branch it is dropped.pnpm tcpasses;pnpm test src/shared/agent-hook-listener src/main/agent-hooks src/wsl-guestpasses (2379 tests);check:code-quality:changedis clean.I did not run a full
orca automations runend to end. The automation completion path (tui-idle) reads the same pane status shown above.Risk / trade-offs
ask_question/ permission prompt no longer shows on the pane (it staysworkingunder the parent). With--dangerously-skip-permissions(automations) nothing changes.agyexits mid-subagent (no final idle Stop), the next conversation started by the user in that terminal clears the parent marker: subagent hooks always have an emptylastUserInput, while user-started conversations carry it. The marker is also cleared on turn-cache and closed-tab cleanup.Fixes #17650