Skip to content

fix(acp): assistant message fragmentation on background tool updates & leaked harness telemetry #13133

Description

@adeebahmad01

Description

When using ACP-backed providers (such as Antigravity) with asynchronous background tools, two interrelated issues corrupt assistant message formatting and clutter thread history:

  1. Abrupt Assistant Segment Severing on Background Tool Updates:
    In AcpSessionRuntime.ts, closeActiveAssistantSegment is invoked unconditionally upon receiving any ToolCallUpdated event:

    if (event._tag === "ToolCallUpdated") {
      yield* closeActiveAssistantSegment({
        queue,
        assistantSegmentRef,
      });

    If a background command finishes while the assistant is actively streaming a response (such as a markdown table, code block, or link), the active segment is severed mid-stream. The remainder of the response is placed in a new segment/bubble without the preceding context, breaking Markdown formatting (e.g. unclosed links [text](http://... cut off before closing parenthesis, and tables split mid-cell where succeeding rows become raw pipe-separated text | row | data |).

  2. Harness Telemetry Parroting (<SYSTEM_MESSAGE>) & Ghost Segments:
    When background tasks complete, reactive system notifications are delivered into the provider context:

    The following is a <SYSTEM_MESSAGE> not actually sent by the user. It is provided by the system as important information to pay attention to.
    <SYSTEM_MESSAGE>
    [Message] timestamp=... sender=.../task-170 priority=... content=Task id finished with result: exit code 0
    </SYSTEM_MESSAGE>
    

    Certain models (e.g. gemini-3.8-flash-high) occasionally parrot this telemetry into their response deltas. Because each tool invocation or update resets the segment lifecycle, this results in an explosion of separate chat bubbles (e.g. 40+ bubbles in a single turn) containing only raw <SYSTEM_MESSAGE> XML boilerplate.

  3. Double Message ID Prefix Bug:
    In ProviderRuntimeIngestion.ts, assistantSegmentMessageId prepends assistant: to baseKey. Since ACP's itemId already begins with assistant:, this results in duplicated prefixes in the database (assistant:assistant:c19d...).


Reproduction Example

Send the following prompt in a thread with an ACP provider supporting background execution:

First, start a background command with run_command and WaitMsBeforeAsync=500:
`sleep 3 && echo "Background task finished successfully"`

Immediately after starting that command (without waiting for it), stream a 50-row Markdown table with columns | Index | Name | Status | Timestamp |. 
Keep writing the rows continuously so that the background task finishes while you are actively streaming the middle of the table.

Actual Behavior:

  1. The assistant begins streaming the table in Bubble 1.
  2. When sleep 3 finishes, ToolCallUpdated is fired.
  3. closeActiveAssistantSegment cuts Bubble 1 off mid-table.
  4. Bubble 2 begins with the remaining rows, but without table headers. The markdown parser fails to render a table, displaying raw | characters and broken elements.
  5. In turns with heavy background tasking, echoed <SYSTEM_MESSAGE> notifications spam the chat UI as individual bubbles.

Expected Behavior:

  • Background tool completions that do not require tool call insertion should not sever an active assistant streaming segment mid-token or mid-block.
  • Provider streaming sanitizers should suppress leaked harness telemetry <SYSTEM_MESSAGE>...</SYSTEM_MESSAGE>.
  • Empty or whitespace-only assistant segments should not be projected as empty bubbles.
  • Message IDs should be cleanly normalized without double assistant:assistant: prefixes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions