Add experimental built-in visualization tools#18785
Add experimental built-in visualization tools#18785LyalinDotCom wants to merge 2 commits intomainfrom
Conversation
Summary of ChangesHello @LyalinDotCom, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates a new experimental feature into the Gemini CLI, enabling the display of various data visualizations directly within the terminal. This enhancement aims to improve the user experience by providing rich, structured visual feedback for complex data, such as charts, tables, and diagrams. It also streamlines the process for models to generate these visualizations by supporting flexible data input formats, making the CLI more powerful for data analysis and presentation. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
| value | ||
| .toLowerCase() | ||
| .replace(/[^a-z0-9]+/g, '-') | ||
| .replace(/^-+|-+$/g, '') || 'node'; |
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data High
|
Size Change: +63.9 kB (+0.26%) Total Size: 24.4 MB
ℹ️ View Unchanged
|
There was a problem hiding this comment.
Code Review
This pull request introduces an experimental but powerful built-in visualization capability to the CLI. The implementation is comprehensive, covering various chart types and including robust data normalization to handle different payload shapes from the LLM. The terminal-native rendering for diagrams is particularly impressive.
My review focuses on two main areas for improvement:
- Architecture: There's significant code duplication between the core tool logic and the UI rendering component. The UI component re-implements data parsing instead of consuming the strongly-typed data structure provided by the core tool. This should be refactored to improve maintainability and reduce the chance of inconsistencies.
- Correctness: A bug in the diagram node ID generation could cause the tool to fail unexpectedly when node labels slugify to the same ID.
Addressing these points will make this new feature more robust and maintainable. Overall, this is a great addition to the Gemini CLI's capabilities.
| case 'bar': { | ||
| const series = asSeries(visualization.data); | ||
| if (series.length === 0) { | ||
| return noDataLine(colors); | ||
| } | ||
| return renderBarLines(series[0], width, visualization.unit).map( | ||
| (text, index) => ({ | ||
| text, | ||
| color: colorAtPalette(colors.palette, index, colors.primary), | ||
| }), | ||
| ); | ||
| } |
There was a problem hiding this comment.
This component seems to be re-implementing data normalization and parsing logic (e.g., asSeries, asSlices, asTable, asDiagram) that is already handled by the RenderVisualizationTool in the @google/gemini-cli-core package. The core tool is designed to produce a strongly-typed VisualizationData object, but this component's VisualizationResult type defines data as Record<string, unknown> and then re-parses it.
This duplication can lead to inconsistencies between the core tool's output and the UI's interpretation, and increases maintenance overhead. The UI component should trust the data structure it receives from the core package.
I recommend refactoring this component to:
- Update the
VisualizationResultinterface to use theVisualizationDatatype from@google/gemini-cli-core. - Remove the
asSeries,asSlices,asTable, andasDiagramhelper functions. - Update
buildKindLinesto directly use the properties of the strongly-typedvisualization.dataobject.
For example, the bar case could be simplified to directly access visualization.data.series:
case 'bar': {
if (!('series' in visualization.data) || visualization.data.series.length === 0) {
return noDataLine(colors);
}
return renderBarLines(visualization.data.series[0], width, visualization.unit).map(
(text, index) => ({
text,
color: colorAtPalette(colors.palette, index, colors.primary),
}),
);
}
| if (ids.has(id)) { | ||
| throw new Error(`Duplicate node id detected: "${id}".`); | ||
| } | ||
| ids.add(id); |
There was a problem hiding this comment.
There's a potential bug in the diagram node ID generation. If two different node labels slugify to the same ID (e.g., "Web UI" and "Web-UI" could both become "web-ui"), and no explicit id is provided, this code will throw a Duplicate node id detected error.
This should be handled more gracefully, similar to how string-only nodes are de-duplicated by appending a suffix. I suggest adding logic to de-duplicate derived IDs to prevent the tool from failing unexpectedly.
| if (ids.has(id)) { | |
| throw new Error(`Duplicate node id detected: "${id}".`); | |
| } | |
| ids.add(id); | |
| if (ids.has(id)) { | |
| // If an explicit ID is provided and it's a duplicate, throw. | |
| if (typeof node['id'] === 'string' && node['id'].trim() === id) { | |
| throw new Error(`Duplicate node id detected: "${id}".`); | |
| } | |
| // Otherwise, it was derived, so de-duplicate. | |
| const baseId = id; | |
| let suffix = 2; | |
| while (ids.has(id)) { | |
| id = `${baseId}-${suffix++}`; | |
| } | |
| } | |
| ids.add(id); |
Summary
This PR introduces an experimental built-in visualization capability for Gemini CLI.
It consolidates visual output into
render_visualizationand adds terminal-native rendering for:barlinepietablediagramIt also improves first-shot tool-call reliability by accepting canonical payloads and common shorthand aliases.
Closes #18784
What changed
render_visualizationtool and wiring in core tool registry.plan/visualer.mdwith the original exploration plan used for this experiment.Notes
Validation
npm run typecheck --workspace @google/gemini-cli-corenpm run typecheck --workspace @google/gemini-clinpm run test --workspace @google/gemini-cli-core -- src/tools/render-visualization.test.ts src/prompts/core/prompts.test.ts src/prompts/core/prompts-substitution.test.tsnpm run test --workspace @google/gemini-cli -- src/ui/components/messages/VisualizationDisplay.test.tsx src/ui/components/messages/ToolResultDisplay.test.tsx