Skip to content

fix(agent-status): an Antigravity subagent finishing no longer ends its parent's turn - #33645

Merged
nwparker merged 2 commits into
mainfrom
nwparker/agint-17650
Oct 25, 2026
Merged

nwparker merged 2 commits into
mainfrom
nwparker/agint-17650

Conversation

@nwparker

@nwparker nwparker commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​95 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​95
Prod 3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​37 $\color{#cf222e}{\Huge{\mathbf{−}}}$​4 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​33

Summary

When an Antigravity agent hands work to its built-in invoke_subagent subagents, Orca was treating the first subagent to finish as the end of the whole run. Automations marked the run completed, recorded the subagent's message as the output, and closed the tab (SIGTERM to agy) 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 agy process, so they fire the same ~/.gemini/config/hooks.json hooks as the parent, using their own conversationId (and their own brain/<id>/…/transcript_full.jsonl). agy 1.4.7 does not fill in the parentConversationId / rootConversationId fields that exist in its HookArgsCommon proto, so those can't be used to spot a subagent. Captured from a live agy 1.4.7 run (fake model endpoint, see below):

PreInvocation   conv=2c4426e4                 (parent)
PreToolUse      conv=2c4426e4  invoke_subagent
PostToolUse     conv=2c4426e4  invoke_subagent
PreInvocation   conv=ab643abd                 (subagent)
Stop            conv=2c4426e4  fullyIdle=false   parent waiting on its subagent
Stop            conv=ab643abd  fullyIdle=true    subagent done  -> main: row "done", msg = subagent report
PreInvocation   conv=2c4426e4                 parent wakes up
Stop            conv=2c4426e4  fullyIdle=true    real end of turn

normalizeAntigravityEvent treated any fullyIdle Stop as terminal, so the subagent's Stop set the pane to done and read the subagent's transcript into lastAssistantMessage. The automation's tui-idle wait then completed. That matches what the reporter saw: close_tab, then SIGTERM, then a completed run whose outputSnapshot held the subagent's report. #31780 can't catch this case because it relies on separate nested processes.

Upstream reference (closed binary agy 1.4.7, strings): the hooks_pb.HookArgsCommon fields conversation_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 the invoke_subagent tool schema (TypeName, Role, Prompt, Workspace).

What changed

  • antigravity-events.ts: when a conversation calls invoke_subagent or send_message, Orca records it as the pane's subagent parent. Until that conversation's own fully idle Stop, hooks from any other conversationId that has no lastUserInput (that is, from subagents) are dropped. A foreign conversation that carries user input replaces the parent. Subagents are created inside the parent's PreToolUse, so the parent is always recorded before any subagent hook arrives.
  • listener-state.ts: a new pane-scoped map antigravitySubagentParentByPaneKey, cleared, moved, and reset alongside the existing Antigravity cache.
  • One regression test that replays the captured event order.

Verification

  • Live repro, no model spend. agy supports AGY_LLM_GATEWAY_URL with AGY_LLM_GATEWAY_WIRE_PROTOCOL=openai. I pointed it at a local scripted fake /v1/chat/completions server (parent calls invoke_subagent → subagent replies after 12 s → parent writes its final report after 5 s), with an isolated HOME.
  • Real Orca app (temporary, uncommitted e2e spec, isolated HOME, background launch). Ran the real agy in an Orca terminal against Orca's managed Antigravity hooks and subscribed to agentStatusByPaneKey:
    • main: working → done "SUBAGENT_REPORT: translation done" (15.46 s) → working → done "PARENT_FINAL_REPORT…" (20.76 s)
    • this branch: working → done "PARENT_FINAL_REPORT…" (20.93 s), with no early done
  • Replaying the captured real payloads through normalizeHookPayload gives the same result: on main the subagent Stop is done with the subagent's message; on this branch it is dropped.
  • New test fails on main and passes here. pnpm tc passes; pnpm test src/shared/agent-hook-listener src/main/agent-hooks src/wsl-guest passes (2379 tests); check:code-quality:changed is clean.

I did not run a full orca automations run end to end. The automation completion path (tui-idle) reads the same pane status shown above.

Risk / trade-offs

  • While subagents are running, a subagent's own tool activity or ask_question / permission prompt no longer shows on the pane (it stays working under the parent). With --dangerously-skip-permissions (automations) nothing changes.
  • If agy exits 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 empty lastUserInput, while user-started conversations carry it. The marker is also cleared on turn-cache and closed-tab cleanup.
  • The shared listener runs on both the main process and the relay, so remote (SSH) panes get the fix once their relay updates. An older relay keeps the old behaviour. No IPC or protocol change.

Fixes #17650

…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
@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent 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: 8121cb5d-f9cd-4e71-a973-0c3b1017386f
Commits

Reviewing files that changed from the base of the PR and between e123924 and 4d90948.

Files selected for processing: 4
  • src/main/agent-hooks/server/server-tab-cleanup.ts
  • src/shared/agent-hook-listener-antigravity.test.ts
  • src/shared/agent-hook-listener/listener-state.ts
  • src/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; 2 remain after this review.

Walkthrough

Antigravity event handling now tracks the conversation ID that starts an in-process subagent for each pane. While that ID is stored, events from a different conversation are ignored unless lastUserInput is present. An idle Stop clears the mapping. Pane cleanup and cache operations also clear or move the mapping. Added tests check parent and child event states, the parent’s final transcript reply, and a subsequent conversation.

Priority: Normal

Merge Risk: Moderate · up to 4d909

A late subagent hook can cause the next conversation on the pane to be ignored. Fix that event ordering before merging unless this risk is explicitly accepted.

Pre-merge checks: Passed 1 · Failed 4

Failed Failed checks: 4 warnings

Check name Status Explanation Resolution
Description check Warning The description follows the template closely. It has a Summary, Root cause, What changed, Verification, and Risk/trade-offs section, plus a Fixes #17650 line. It explains the mechanism and the before/… Add the missing template sections: an ELI5 explanation in plain language, a 'Why' section that explains why this approach was chosen over the alternatives, and a Visual Proof section with before/after evidence (video or screenshots) for the…
Linked Issues check Warning Issue #17650 requires the Codex automation to remain active while a nested codex exec runs and to capture the root agent response. The supplied change summary lists only Antigravity hook handling, A… Implement and test the #17650 Codex behavior in the Codex hook or automation completion path. The test must keep the run active through nested codex exec completion and capture the root response. Otherwise, remove the Fixes #17650 linka…
Out of Scope Changes check Warning The changed implementation is provider-specific to Antigravity. Issue #17650 concerns scheduled Codex automations and nested codex exec processes. The supplied change summary does not show a Codex o… Remove these Antigravity-only changes from this issue's pull request, or link them to an applicable Antigravity issue and submit the required Codex fix separately.
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 1 passed
Check name Status Explanation
Title check Passed The title names the main change: an Antigravity subagent finishing no longer ends its parent's turn. This matches the summarized code changes, which drop subagent hooks on the pane until the parent's …
Full details: Title check

Explanation

The title names the main change: an Antigravity subagent finishing no longer ends its parent's turn. This matches the summarized code changes, which drop subagent hooks on the pane until the parent's own fully idle Stop, and the PR objectives. It uses the conventional fix(scope) form and is 85 characters, which is slightly long but still clear.

Full details: Description check

Explanation

The description follows the template closely. It has a Summary, Root cause, What changed, Verification, and Risk/trade-offs section, plus a Fixes #17650 line. It explains the mechanism and the before/after behavior, and it lists the tests run. It does not include the template's ELI5, Why (alternatives considered), or Visual Proof sections, and it does not address the Testing checkboxes, AI Disclosure, or Review sections. The Visual Proof gap matters because the change alters user-visible pane status, and the template requires before/after evidence for behavior changes. The author gives text-based status traces and a live test log instead of a before/after video or screenshot. The 'Fixes #17650' link also refers to a Codex-specific issue, and the PR objectives note that the Antigravity implementation does not reproduce that Codex case end to end. The core content is complete, but several required template sections are missing.

Resolution

Add the missing template sections: an ELI5 explanation in plain language, a 'Why' section that explains why this approach was chosen over the alternatives, and a Visual Proof section with before/after evidence (video or screenshots) for the user-visible pane status change, or N/A with a reason if the author judges it not applicable. Complete the Testing checkboxes and state the platforms tested (macOS, Linux, Windows, SSH). Fill in the AI Disclosure section if an AI model was used. Complete the Review and Agent skill upstream boundary sections. Confirm that the Fixes #17650 link is correct, since that issue describes Codex automations, not Antigravity. Consider stating that the Antigravity fix does not close the Codex case.

Full details: Linked Issues check

Explanation

Issue #17650 requires the Codex automation to remain active while a nested codex exec runs and to capture the root agent response. The supplied change summary lists only Antigravity hook handling, Antigravity listener state, Antigravity tests, and tab cleanup. It shows no Codex path, generic automation completion change, or test for nested codex exec. The reported verification covers only Antigravity invoke_subagent behavior.

Resolution

Implement and test the #17650 Codex behavior in the Codex hook or automation completion path. The test must keep the run active through nested codex exec completion and capture the root response. Otherwise, remove the Fixes #17650 linkage and link the applicable Antigravity issue.

Full details: Out of Scope Changes check

Explanation

The changed implementation is provider-specific to Antigravity. Issue #17650 concerns scheduled Codex automations and nested codex exec processes. The supplied change summary does not show a Codex or provider-independent completion change. Therefore, the Antigravity implementation and its regression test do not stay within the linked issue's stated scope.

Resolution

Remove these Antigravity-only changes from this issue's pull request, or link them to an applicable Antigravity issue and submit the required Codex fix separately.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

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 #17650 attribution or add Codex-specific coverage.

This fixture covers Antigravity invoke_subagent events only. It does not establish that a scheduled Codex automation with nested codex exec resumes the parent or captures the parent’s final response. Remove #17650 from 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
Commits

Reviewing files that changed from the base of the PR and between 47d1b31 and e123924.

Files selected for processing: 3
  • src/shared/agent-hook-listener-antigravity.test.ts
  • src/shared/agent-hook-listener/listener-state.ts
  • src/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)

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.

Major · Functional Correctness · Quick win

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.
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.

[Bug]: Automation run completes when a nested codex exec exits

1 participant