adk-web icon indicating copy to clipboard operation
adk-web copied to clipboard

adk web UI merges thought part and text response part into a single chat bubble

Open valentinozegna opened this issue 1 month ago • 8 comments

Describe the bug When BuiltInPlanner is assigned to the root_agent, the adk web UI merges the thought and the response of the agent into a single bubble.

To Reproduce

  1. Create a very simple agent and assign it the BuiltInPlanner:
"""
Simple agent for GitHub issue reproduction.
Minimal configuration with BuiltInPlanner matching westworld agent setup.
"""

from google.adk.agents import LlmAgent
from google.adk.planners import BuiltInPlanner
from google.genai.types import HttpRetryOptions, GenerateContentConfig, ThinkingConfig
from google.adk.models import Gemini


root_agent = LlmAgent(
    name="simple_agent",
    description="A simple helpful assistant for testing",
    instruction="You are a helpful assistant, respond to user's queries",
    model=Gemini(
        model="gemini-2.5-pro",
        retry_options=HttpRetryOptions(
            attempts=3,
            initial_delay=1.0,
            max_delay=60.0,
            exp_base=2.0,
            jitter=0.2,
        ),
    ),
    planner=BuiltInPlanner(
        thinking_config=ThinkingConfig(
            include_thoughts=True,
            thinking_budget=8192,
        ),
    ),
    generate_content_config=GenerateContentConfig(
        temperature=0.0,
    ),
    output_key="chat_response",
)

  1. Run adk web
  2. Ask any question

Expected behavior The thought should be shown as a separate entry in the chat UI. Instead, thought and response are merged.

Screenshots Image

Desktop (please complete the following information):

  • OS: macOS
  • Python 3.12.12
  • ADK version: 1.18.0

Model Information:

  • Are you using LiteLLM: No
  • gemini-2.5-pro

valentinozegna avatar Nov 14 '25 22:11 valentinozegna

To add some more context, if I use LiteLLM, the thoughts are not shown at all in adk web, they are just not part of the response object, even when using BuiltInPlanner with include_thoughts=True.

Sample Code

"""
Simple agent for GitHub issue reproduction.
Minimal configuration with BuiltInPlanner using LiteLLM.
"""

from google.adk.agents import LlmAgent
from google.adk.planners import BuiltInPlanner
from google.genai.types import GenerateContentConfig, ThinkingConfig
from google.adk.models.lite_llm import LiteLlm


root_agent = LlmAgent(
    name="simple_agent",
    description="A simple helpful assistant for testing",
    instruction="You are a helpful assistant, respond to user's queries",
    model=LiteLlm(model="gemini/gemini-2.5-pro"),
    planner=BuiltInPlanner(
        thinking_config=ThinkingConfig(
            include_thoughts=True,
            thinking_budget=8192,
        ),
    ),
    generate_content_config=GenerateContentConfig(
        temperature=0.0,
    ),
    output_key="chat_response",
)

Screenshot

Image

valentinozegna avatar Nov 14 '25 22:11 valentinozegna

@valentinozegna The Python backend correctly sends thought and text as separate Part objects with the thought=True flag. The issue is in the adk-web frontend which merges these parts into a single bubble. This needs to be fixed in the adk-web repository by checking part.thought and rendering thought parts in a distinct style (e.g., separate bubble with different styling). we are looking more into it.

For the LiteLLM issue: thoughts won't appear with LiteLLM due to API limitations - use the Gemini native model instead for thought support. Thanks!

surajksharma07 avatar Nov 17 '25 07:11 surajksharma07

Yep, I understand the issue is in how the adk-web processes the response object from the backend. The funny thing is that this was working totally fine as of few months ago, thoughts used to be rendered as separate expandable cards. I don't know at what point this bug was introduced.

valentinozegna avatar Nov 17 '25 08:11 valentinozegna

@valentinozegna Thank you for this information.The fact that thoughts used to render as separate expandable cards and this is a regression (not a missing feature) significantly narrows down our investigation.

This helps us focus on identifying what changed in adk-web that broke the rendering. If you happen to remember which ADK version was working correctly, or approximately when you noticed it stopped working (e.g., after updating to a specific version), that would be very helpful for pinpointing when the regression was introduced.

We'll coordinate with the adk-web team to investigate the frontend changes that may have caused this. Since the Python backend is correctly sending separate Part objects with the thought=True flag (as confirmed in our analysis), this is definitely an adk-web rendering regression that needs to be tracked down and fixed. we are looking more deep dive into it.

Thank you for your patience and for providing this timeline context.

surajksharma07 avatar Nov 17 '25 10:11 surajksharma07

@xuanyang15 Please have a look into it.

surajksharma07 avatar Nov 17 '25 10:11 surajksharma07

Check out this issue on adk-web:

https://github.com/google/adk-web/issues/265

valentinozegna avatar Nov 17 '25 19:11 valentinozegna

@wyf7107 Could you please help confirm if this a UI issue or backend issue?

xuanyang15 avatar Nov 18 '25 01:11 xuanyang15

Seems like this is working correctly now.

valentinozegna avatar Nov 28 '25 21:11 valentinozegna