Skip to content

Streaming thought chunks render as separate bubbles instead of consolidating #443

Description

@ferponse

Description

When using streaming mode (SSE) with models that emit thinking/reasoning content (e.g., Claude with extended thinking via LiteLLM, or Gemini with thinking_config), each partial ReasoningChunk renders as a separate "Thought" bubble in the Dev UI instead of being consolidated into a single thought block.

Non-streaming mode correctly shows a single consolidated "Thought" bubble.

Steps to Reproduce

  1. Configure an ADK agent with a model that supports thinking/reasoning (e.g., vertex_ai/claude-sonnet-4-6 via LiteLlm with thinking={"type": "enabled", "budget_tokens": 10000})
  2. Run adk web and open the Dev UI
  3. Send a message to the agent
  4. Observe the event timeline — each streaming thought chunk appears as a separate "Thought" bubble (e.g., remove more unused comments #2 "The user said", add more comment #3 '"hola" (', first commit on README #4 "hello).", etc.)

Expected Behavior

Consecutive partial thought events should be consolidated into a single "Thought" bubble that progressively accumulates text, similar to how text response chunks are merged into a single response bubble.

Actual Behavior

Each ReasoningChunk partial generates a separate "Thought" bubble in the timeline, resulting in dozens of fragmented thought events for a single reasoning block.

Analysis

The consolidation logic in chat.component.ts (lines ~1237-1257) attempts to merge thought partials by searching for an existing event with partial=true and thought=true. However, buildUiEventFromEvent creates a new UiEvent with only the current chunk's content, and the replacement at line ~1285 (newEvents[existingIndex] = uiEvent) replaces rather than accumulates the text. This causes either:

  • The consolidation search to fail (resulting in multiple bubbles), or
  • The previous thought to be replaced instead of appended to

Environment

  • ADK Python: v1.32.0
  • ADK Web: latest (cloned from main)
  • Model: vertex_ai/claude-sonnet-4-6 via LiteLlm with extended thinking enabled
  • Also reproducible with native LiteLlm (not just custom BaseLlm subclasses)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions