Repository navigation
Description
Summary
When an Antigravity ACP agent (gemini-4-argon / localharness_external) invokes run_command and the command exceeds WaitMsBeforeAsync (converting into a background task task-<N>), the agent's system instructions require it to emit a short status update to the user and stop calling tools to wait for the background task to complete:
"After launching a background task such as 'run_command', YOU MUST TAKE ONE OF THE FOLLOWING TWO ACTIONS: A) either proceed to other relevant work (if any) or, B) simply update the user with a short message (e.g. 'task-20 has been launched in the background. I will wait for it to complete before proceeding.') and end the turn. DO NOTHING ELSE."
When the agent follows Path B—emitting an assistant text message (agent_message_chunk) and ending its planner step without calling any further tools while the background run_command is still running—the assistant message item in T3 Code remains permanently stuck in streaming: true (status: "running") for the entire duration of the background command (or indefinitely if the background command hangs).
In Paragraph streaming mode (assistantDeliveryMode: "paragraph"), this also withholds the final paragraph buffer of the assistant's message from rendering until the background task finishes or the user manually interrupts/messages the thread.
Reproduction Steps
- Start an Antigravity ACP session in T3 Code (
gemini-4-argon). - Ask the agent to run a CLI command that takes longer than
WaitMsBeforeAsync(i.e.> 10s, such as a preview build/deployment CLI or long-running test suite) and wait for it. - Observe the event sequence:
tool_call(kind: "execute",title: "run_command",status: "in_progress") is emitted.- After
WaitMsBeforeAsync(10s), Antigravity moves the command to a background task (task-<N>) and completes the synchronous tool step so the planner can continue. - The agent emits an
agent_message_chunkexplaining thattask-<N>is running in the background and ends its planner step (StepStatus.DONE) to wait for the reactive wakeup.
- Observe the T3 Code conversation UI while
task-<N>continues running in the background.
Expected Behavior
- Once the planner step finishes emitting the assistant message and transitions into waiting on the background task (
STATE_WAITING_FOR_TASKS), the assistant message stream is closed (streaming: false,status: "completed") and all buffered text is flushed to the UI, while the turn/background task indicator reflects that background work is still running.
Actual Behavior
- The assistant message item in
orchestration_v2_projection_turn_itemsstays stuck at:{ "kind": "assistant_message", "status": "running", "data": { "text": "...", "streaming": true } } - The UI displays the assistant text as perpetually streaming/hanging for minutes (until the background task exits or the user sends a follow-up message / interrupts).
Root Cause Analysis
This happens due to the interaction between Antigravity ACP's LocalHarnessEventProcessor and T3 Code's makeAcpAdapterV2 (packages/provider-acp/src/server/adapter.ts):
-
Antigravity ACP keeps
session/promptopen duringSTATE_WAITING_FOR_TASKS:- In
antigravity-acp(localharness_external/acp/session.py),LocalHarnessEventProcessor.process_eventinspectsevent.trajectory_status.status. - When a background
run_command(task-<N>) is still running (hasActiveTasks() == true), the trajectory transitions toSTATE_WAITING_FOR_TASKS(4) rather thanSTATE_FULLY_IDLE(2). - Because
self.is_idle.set()is only triggered onSTATE_FULLY_IDLEorSTATE_CANCELLED, thesession/promptJSON-RPC request remains open for the entire lifetime of the background command.
- In
-
makeAcpAdapterV2only closescontext.assistant.currenton a new stream, new tool call, orsession/promptresolution:- In
packages/provider-acp/src/server/adapter.ts,appendText(context, "assistant", update.content.text)creates/updatescontext.assistant.currentwithstreaming: true(status: "running"). closeTextStream(context, "assistant")is currently only called when:- A
reasoningoruserstream starts (appendTextfor another stream kind), - A new tool call is emitted (
emitTool), or turn.settled/finalizeTurnruns aftersession/promptresolves (closeAllTextStreams(context)).
- A
- Because the agent has already emitted its "waiting for background task" message after the
run_commandtool call and then stops calling tools to wait onSTATE_WAITING_FOR_TASKS, no subsequentemitToolorreasoningchunk arrives, andsession/promptdoes not resolve until the background task finishes. Consequently,closeTextStream(context, "assistant")is never invoked during the wait.
- In
Relationship to Existing Issues & PRs
- Related to Antigravity ACP (Gemini 4 Argon): Streaming text gets stuck in running/streaming state & thoughts are never streamed #28172, [Bug]: Antigravity ACP background tasks are marked completed when the agent stops to wait, hiding active background tasks and dropping agent wakeups in the UI #28415, Assistant streaming in 'paragraph' mode withholds final paragraph while turn remains open on background tool calls, and steering a delegated wake run disposes sibling app_owned subagent wakeups #28175, and Antigravity: a command still running after the reply is marked completed, and Stop cannot end it #16442.
- Note on open PR fix(server): keep Antigravity commands active and show wakeups #28450 (
fix(server): keep Antigravity commands active and show wakeups): fix(server): keep Antigravity commands active and show wakeups #28450 updatesAntigravityAdapterV2.tsandpackages/provider-acp/src/server/adapter.tssoexecutetool calls are tracked as background work (deferFinalizeForBackgroundWork: true,enablePostSettleContinuation: true), which fixes premature tool completion whensession/promptsettles early. However, whensession/promptitself stays open waiting on a backgroundrun_command(STATE_WAITING_FOR_TASKS) after the agent emits its status message,context.assistant.currentstill remains open (streaming: true) unless the assistant text stream is explicitly closed/flushed when the planner step finishes or enters idle-wait.
Activity
juliusmarminge commentedon Nov 1, 2026
Duplicate of #28172 (git.cafe). Both report the same thing: the Antigravity ACP
assistant_messagestaysstreaming: true/runningbecause Antigravity holdssession/promptopen inSTATE_WAITING_FOR_TASKS, andmakeAcpAdapterV2closes the assistant stream only on a new text stream, a tool call, or prompt settlement. https://git.cafe/pingdotgg/t3code/issues/28172 already gives this as its root cause 4, and its suggested fix 1 is the same fix.Checked on main at
01a93e7b51:packages/provider-acp/src/server/adapter.tsstill closescontext.assistant.currentonly on those three paths. The paragraph-mode half (the held final paragraph) is tracked in #28175, with an open PR, #28221. Closing this one so the work stays in https://git.cafe/pingdotgg/t3code/issues/28172.