gemini-cli - ✅(Solved) Fix [AgentProtocol] Formalize unified DisplayContent and DisplayName metadata via isolated toolDisplay prop [3 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
google-gemini/gemini-cli#25046Fetched 2026-04-10 03:44:58
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
0
Author
Participants
Assignees
Timeline (top)
labeled ×2assigned ×1parent_issue_added ×1renamed ×1

Currently, visual metadata (like display names, descriptions, and result summaries) is inconsistent across different AgentEvent types. To achieve a true "dumb terminal" TUI, the protocol must provide structured, multi-representation content that the UI can render without knowing the specific context of the event.

To ensure the existing useGeminiStream path remains 100% untouched, the new metadata must be isolated into a dedicated toolDisplay property that triggers an alternate rendering path in the UI components.

Root Cause

Currently, visual metadata (like display names, descriptions, and result summaries) is inconsistent across different AgentEvent types. To achieve a true "dumb terminal" TUI, the protocol must provide structured, multi-representation content that the UI can render without knowing the specific context of the event.

To ensure the existing useGeminiStream path remains 100% untouched, the new metadata must be isolated into a dedicated toolDisplay property that triggers an alternate rendering path in the UI components.

PR fix notes

PR #25101: refactor(core): consolidate execute() arguments into ExecuteOptions

Description (problem / solution / changelog)

Summary

Consolidate ToolInvocation.execute() arguments into a single ExecuteOptions object. This simplifies the tool execution interface and makes it easier to extend with optional properties without changing positional argument signatures.

Details

  • Updated ExecuteOptions in packages/core/src/tools/tools.ts to include signal and updateOutput.
  • Refactored ToolInvocation.execute() to accept only ExecuteOptions.
  • Migrated all tool implementations and agent invocation classes to the new signature.
  • Mass-replaced all call sites in packages/core, packages/cli, and packages/sdk using a script and manual cleanup.
  • This is a non-behavioral refactor that sets the stage for adding more display-related properties to tool execution.

Related Issues

Related to #25046

How to Validate

npm run preflight to verify all tests, linting, and types pass across the monorepo.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run

Changed files

  • integration-tests/ripgrep-real.test.ts (modified, +12/-4)
  • packages/a2a-server/src/commands/memory.ts (modified, +2/-2)
  • packages/cli/src/acp/acpClient.ts (modified, +4/-2)
  • packages/cli/src/ui/hooks/atCommandProcessor.ts (modified, +1/-1)
  • packages/core/src/agents/agent-tool.ts (modified, +7/-6)
  • packages/core/src/agents/browser/analyzeScreenshot.test.ts (modified, +19/-7)
  • packages/core/src/agents/browser/analyzeScreenshot.ts (modified, +2/-1)
  • packages/core/src/agents/browser/browserAgentInvocation.test.ts (modified, +53/-33)
  • packages/core/src/agents/browser/browserAgentInvocation.ts (modified, +3/-5)
  • packages/core/src/agents/browser/mcpToolWrapper.test.ts (modified, +22/-10)
  • packages/core/src/agents/browser/mcpToolWrapper.ts (modified, +2/-1)
  • packages/core/src/agents/local-invocation.test.ts (modified, +29/-17)
  • packages/core/src/agents/local-invocation.ts (modified, +3/-5)
  • packages/core/src/agents/remote-invocation.test.ts (modified, +44/-20)
  • packages/core/src/agents/remote-invocation.ts (modified, +3/-5)
  • packages/core/src/core/coreToolHookTriggers.test.ts (modified, +2/-6)
  • packages/core/src/core/coreToolHookTriggers.ts (modified, +6/-6)
  • packages/core/src/test-utils/mock-tool.ts (modified, +6/-11)
  • packages/core/src/tools/activate-skill.test.ts (modified, +6/-2)
  • packages/core/src/tools/activate-skill.ts (modified, +2/-1)
  • packages/core/src/tools/ask-user.test.ts (modified, +9/-3)
  • packages/core/src/tools/ask-user.ts (modified, +2/-1)
  • packages/core/src/tools/complete-task.test.ts (modified, +9/-3)
  • packages/core/src/tools/complete-task.ts (modified, +3/-1)
  • packages/core/src/tools/edit.test.ts (modified, +40/-18)
  • packages/core/src/tools/edit.ts (modified, +2/-1)
  • packages/core/src/tools/enter-plan-mode.test.ts (modified, +10/-4)
  • packages/core/src/tools/enter-plan-mode.ts (modified, +2/-1)
  • packages/core/src/tools/exit-plan-mode.test.ts (modified, +38/-16)
  • packages/core/src/tools/exit-plan-mode.ts (modified, +2/-1)
  • packages/core/src/tools/get-internal-docs.test.ts (modified, +4/-4)
  • packages/core/src/tools/get-internal-docs.ts (modified, +2/-1)
  • packages/core/src/tools/glob.test.ts (modified, +16/-16)
  • packages/core/src/tools/glob.ts (modified, +2/-1)
  • packages/core/src/tools/grep.test.ts (modified, +20/-20)
  • packages/core/src/tools/grep.ts (modified, +2/-1)
  • packages/core/src/tools/line-endings.test.ts (modified, +3/-3)
  • packages/core/src/tools/ls.test.ts (modified, +14/-14)
  • packages/core/src/tools/ls.ts (modified, +2/-1)
  • packages/core/src/tools/mcp-tool.test.ts (modified, +55/-42)
  • packages/core/src/tools/mcp-tool.ts (modified, +2/-1)
  • packages/core/src/tools/memoryTool.test.ts (modified, +6/-6)
  • packages/core/src/tools/memoryTool.ts (modified, +2/-1)
  • packages/core/src/tools/read-file.test.ts (modified, +17/-17)
  • packages/core/src/tools/read-file.ts (modified, +2/-1)
  • packages/core/src/tools/read-many-files.test.ts (modified, +70/-24)
  • packages/core/src/tools/read-many-files.ts (modified, +5/-4)
  • packages/core/src/tools/ripGrep.test.ts (modified, +41/-37)
  • packages/core/src/tools/ripGrep.ts (modified, +2/-1)
  • packages/core/src/tools/shell.test.ts (modified, +36/-28)
  • packages/core/src/tools/shell.ts (modified, +7/-7)
  • packages/core/src/tools/shellBackgroundTools.integration.test.ts (modified, +6/-6)
  • packages/core/src/tools/shellBackgroundTools.test.ts (modified, +30/-10)
  • packages/core/src/tools/shellBackgroundTools.ts (modified, +4/-2)
  • packages/core/src/tools/tool-registry.test.ts (modified, +3/-1)
  • packages/core/src/tools/tool-registry.ts (modified, +5/-4)
  • packages/core/src/tools/tools.ts (modified, +12/-16)
  • packages/core/src/tools/topicTool.test.ts (modified, +6/-2)
  • packages/core/src/tools/topicTool.ts (modified, +2/-1)
  • packages/core/src/tools/trackerTools.ts (modified, +24/-7)
  • packages/core/src/tools/web-fetch.test.ts (modified, +59/-23)
  • packages/core/src/tools/web-fetch.ts (modified, +2/-1)
  • packages/core/src/tools/web-search.test.ts (modified, +5/-5)
  • packages/core/src/tools/web-search.ts (modified, +4/-1)
  • packages/core/src/tools/write-file.test.ts (modified, +11/-11)
  • packages/core/src/tools/write-file.ts (modified, +4/-1)
  • packages/core/src/tools/write-todos.ts (modified, +2/-4)
  • packages/sdk/src/tool.test.ts (modified, +10/-4)
  • packages/sdk/src/tool.ts (modified, +5/-4)

PR #25134: feat(agent): implement tool-controlled display protocol (Steps 2-3)

Description (problem / solution / changelog)

Summary

Implement tool-controlled display protocol (Steps 2-3) for AgentProtocol / useAgentSession. This allows tools to provide structured visual metadata (name, description, result summary, and rich results like diffs) directly to the UI, replacing ad-hoc logic in the frontend.

Details

  • Protocol Changes: Added ToolDisplay interface and related types (DisplayText, DisplayDiff, DisplayContent) to packages/core/src/agent/types.ts.
  • Cleanup: Removed legacy displayContent property from ToolUpdate and ToolResponse in favor of the new display: ToolDisplay.
  • Centralized Logic: Added populateToolDisplay utility in packages/core/src/agent/tool-display-utils.ts to handle the transition and provide a consistent way for translators to build display metadata.
  • Translators: Updated event-translator.ts and legacy-agent-session.ts to use the new display property.
  • CLI Support: Updated IndividualToolCallDisplay and useAgentStream to consume and store the new display property.
  • Type Safety: Renamed Message to AgentMessage in the protocol types to avoid conflicts with other Message definitions in the codebase.

Related Issues

Related to #25046 (Steps 2 & 3)

How to Validate

  1. Run core tests: npm run test -w @google/gemini-cli-core
  2. Run CLI tests: npm run test -w @google/gemini-cli
  3. Verify type check: npm run typecheck

Pre-Merge Checklist

  • Added/updated tests
  • Noted breaking changes (Internal protocol change, removed displayContent)
  • Validated on MacOS

Changed files

  • packages/cli/src/nonInteractiveCliAgentSession.ts (modified, +5/-2)
  • packages/cli/src/ui/hooks/useAgentStream.ts (modified, +12/-6)
  • packages/cli/src/ui/types.ts (modified, +2/-0)
  • packages/core/src/agent/content-utils.test.ts (modified, +0/-22)
  • packages/core/src/agent/content-utils.ts (modified, +0/-18)
  • packages/core/src/agent/event-translator.test.ts (modified, +14/-9)
  • packages/core/src/agent/event-translator.ts (modified, +10/-5)
  • packages/core/src/agent/legacy-agent-session.test.ts (modified, +4/-3)
  • packages/core/src/agent/legacy-agent-session.ts (modified, +8/-5)
  • packages/core/src/agent/tool-display-utils.test.ts (added, +124/-0)
  • packages/core/src/agent/tool-display-utils.ts (added, +106/-0)
  • packages/core/src/agent/types.ts (modified, +24/-5)
  • packages/core/src/index.ts (modified, +9/-0)

PR #25186: refactor(cli): migrate core tools to native ToolDisplay property and fix UI rendering

Description (problem / solution / changelog)

Summary

This PR migrates the core CLI tools and rendering pipeline to emit and consume a native ToolDisplay object, deprecating the legacy returnDisplay adapter. By shifting control of the display schema directly to the tools themselves, the UI can now render tool responses more predictably across both compact (DenseToolMessage) and full-width (ToolMessage) views.

Fixes #25046

Details

1. Core Tool Migrations

The following core tools have been updated to populate and emit their own ToolDisplay objects (including name, description, resultSummary, and result), bypassing the legacy translation layer:

  • edit
  • grep / ripGrep
  • ls
  • shell
  • read-file
  • write-file

2. Event Pipeline & Type Updates

  • Updated ToolCallResponseInfo, event-translator, and tool-executor to process the new ToolDisplay property.
  • Fixed a bug in populateToolDisplay (tool-display-utils.ts) where legacy JSON payloads were indiscriminately overwriting explicitly defined result: null values from tools like ripGrep.

3. UI & Rendering Fixes

  • State mapping: useAgentStream now seamlessly bridges the new display property into IndividualToolCallDisplay.
  • Compact View Allowance: ToolGroupMessage now checks tool.originalRequestName instead of just tool.name to determine if a tool supports the compact view. This allows subagent-aliased tools (like SearchText) to correctly render as compact DenseToolMessage components.
  • Summary Deduplication: Fixed an issue in ToolMessage and ToolShared where tool summaries were duplicated in both the header line and the result box. If a tool explicitly sets display.result to null, the summary is rendered in the box, and automatically hidden from the header.

Related Issues

Fixes #25046

How to Validate

  1. Run an agent flow invoking migrated tools (e.g. ls, read_file, grep_search).
  2. Verify that tools supporting compact output render on a single line with DenseToolMessage.
  3. Check that aliased tools (like SearchText in subagents) successfully trigger the compact view.
  4. Ensure that tools returning result: null (like grep_search) cleanly render their summary in the main box when forced into a non-compact view, without duplicating the summary in the header.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

Changed files

  • packages/cli/src/nonInteractiveCliAgentSession.ts (modified, +5/-2)
  • packages/cli/src/ui/components/HistoryItemDisplay.tsx (modified, +7/-0)
  • packages/cli/src/ui/components/messages/ToolGroupDisplay.test.tsx (added, +304/-0)
  • packages/cli/src/ui/components/messages/ToolGroupDisplay.tsx (added, +267/-0)
  • packages/cli/src/ui/components/messages/__snapshots__/ToolGroupDisplay.test.tsx.snap (added, +79/-0)
  • packages/cli/src/ui/hooks/useAgentStream.ts (modified, +71/-34)
  • packages/cli/src/ui/types.ts (modified, +17/-0)
  • packages/core/src/agent/content-utils.test.ts (modified, +0/-22)
  • packages/core/src/agent/content-utils.ts (modified, +0/-18)
  • packages/core/src/agent/event-translator.test.ts (modified, +14/-9)
  • packages/core/src/agent/event-translator.ts (modified, +13/-6)
  • packages/core/src/agent/legacy-agent-session.test.ts (modified, +14/-4)
  • packages/core/src/agent/legacy-agent-session.ts (modified, +9/-5)
  • packages/core/src/agent/tool-display-utils.test.ts (added, +124/-0)
  • packages/core/src/agent/tool-display-utils.ts (added, +109/-0)
  • packages/core/src/agent/types.ts (modified, +60/-5)
  • packages/core/src/config/config.ts (modified, +8/-2)
  • packages/core/src/core/geminiChat.ts (modified, +4/-0)
  • packages/core/src/core/turn.ts (modified, +25/-1)
  • packages/core/src/index.ts (modified, +9/-0)
  • packages/core/src/scheduler/scheduler.ts (modified, +11/-0)
  • packages/core/src/scheduler/state-manager.ts (modified, +7/-1)
  • packages/core/src/scheduler/tool-executor.ts (modified, +8/-0)
  • packages/core/src/scheduler/types.ts (modified, +5/-0)
  • packages/core/src/tools/edit.test.ts (modified, +11/-0)
  • packages/core/src/tools/edit.ts (modified, +23/-0)
  • packages/core/src/tools/grep.ts (modified, +10/-1)
  • packages/core/src/tools/ls.ts (modified, +5/-0)
  • packages/core/src/tools/read-file.test.ts (modified, +24/-8)
  • packages/core/src/tools/read-file.ts (modified, +12/-0)
  • packages/core/src/tools/ripGrep.ts (modified, +10/-1)
  • packages/core/src/tools/shell.test.ts (modified, +6/-0)
  • packages/core/src/tools/shell.ts (modified, +16/-0)
  • packages/core/src/tools/tools.ts (modified, +7/-0)
  • packages/core/src/tools/topicTool.ts (modified, +5/-0)
  • packages/core/src/tools/write-file.test.ts (modified, +10/-0)
  • packages/core/src/tools/write-file.ts (modified, +13/-0)

Code Example

export type DisplayContent = {
    type: 'text';
    contentType?: 'text/markdown' | 'text/ansi-color' | 'text/plain';
    text: string;
  };

---

export type DisplayDiff = {
    type: 'diff';
    path?: string;
    diff?: string; // Unified diff string
    beforeText: string;
    afterText: string;
  };

---

toolDisplay?: {
    displayName: string;
    displaySummary?: DisplayContent;
    displayContent?: DisplayContent | DisplayDiff;
  };
RAW_BUFFERClick to expand / collapse

Context

Currently, visual metadata (like display names, descriptions, and result summaries) is inconsistent across different AgentEvent types. To achieve a true "dumb terminal" TUI, the protocol must provide structured, multi-representation content that the UI can render without knowing the specific context of the event.

To ensure the existing useGeminiStream path remains 100% untouched, the new metadata must be isolated into a dedicated toolDisplay property that triggers an alternate rendering path in the UI components.

Tasks

1. Define Discriminated Union Types (packages/core/src/agent/types.ts)

  • Define DisplayContent:
    export type DisplayContent = {
      type: 'text';
      contentType?: 'text/markdown' | 'text/ansi-color' | 'text/plain';
      text: string;
    };
  • Define DisplayDiff:
    export type DisplayDiff = {
      type: 'diff';
      path?: string;
      diff?: string; // Unified diff string
      beforeText: string;
      afterText: string;
    };
  • Add displayName: string, displaySummary: DisplayContent, and displayContent: DisplayContent | DisplayDiff to Agent Protocol events:
    • ToolRequest
    • ToolUpdate
    • ToolResponse
    • ElicitationRequest

2. Isolate UI Data Structure (packages/cli/src/ui/types.ts)

  • Add an optional toolDisplay field to IndividualToolCallDisplay:
    toolDisplay?: {
      displayName: string;
      displaySummary?: DisplayContent;
      displayContent?: DisplayContent | DisplayDiff;
    };
  • Constraint: Do not modify the existing resultDisplay, name, or description fields to avoid breaking legacy tool mapping (toolMapping.ts).

3. Bifurcated Rendering (packages/cli/src/ui/components/messages/ToolResultDisplay.tsx)

  • Implement a clean if (props.toolDisplay) branch.
  • New Path: Use structured metadata with priority: ANSI > Markdown > Plain. Respect explicit empty strings ('') for elision. Use DisplayDiff for rich diffs.
  • Legacy Path: Keep the original rendering logic exactly as it is for when toolDisplay is absent.
  • Update parent components (ToolMessage, ShellToolMessage, DenseToolMessage) to pass toolDisplay through.

4. Clean Ingestion (packages/cli/src/ui/hooks/useAgentStream.ts)

  • Map incoming Agent Protocol events into the new toolDisplay property.
  • Ensure useGeminiStream.ts and toolMapping.ts leave toolDisplay undefined.

Acceptance Criteria

  • useGeminiStream rendering is identical to the baseline (no regressions in legacy mode).
  • useAgentStream utilizes structured metadata for consistent, context-agnostic tool display.
  • DisplayDiff correctly leverages the existing DiffRenderer.
  • Explicit empty strings in the protocol result in elided UI output.

extent analysis

TL;DR

To achieve a consistent and context-agnostic tool display, implement the new toolDisplay property in the Agent Protocol events and update the UI components to render structured metadata.

Guidance

  • Define the DisplayContent and DisplayDiff types in packages/core/src/agent/types.ts to provide a structured format for metadata.
  • Update the UI components in packages/cli/src/ui/components/messages/ToolResultDisplay.tsx to render the new toolDisplay property, prioritizing ANSI, Markdown, and Plain text formats.
  • Ensure the useAgentStream hook in packages/cli/src/ui/hooks/useAgentStream.ts maps incoming Agent Protocol events into the new toolDisplay property without modifying the existing useGeminiStream path.
  • Verify that the new implementation meets the acceptance criteria, including identical rendering for useGeminiStream and correct utilization of structured metadata for useAgentStream.

Example

// packages/core/src/agent/types.ts
export type DisplayContent = {
  type: 'text';
  contentType?: 'text/markdown' | 'text/ansi-color' | 'text/plain';
  text: string;
};

export type DisplayDiff = {
  type: 'diff';
  path?: string;
  diff?: string; // Unified diff string
  beforeText: string;
  afterText: string;
};

Notes

The implementation should ensure that the existing useGeminiStream path remains unchanged to avoid regressions in legacy mode. The new toolDisplay property should be used to render structured metadata, and explicit empty strings in the protocol should result in elided UI output.

Recommendation

Apply the workaround by implementing the new toolDisplay property and updating the UI components to render structured metadata, as this will provide a consistent and context-agnostic tool display without modifying the existing useGeminiStream path.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING