Skip to content

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

@ferponse

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions