Skip to content

GIE-394: Render Perses charts for observability data#112

Open
eyevana wants to merge 4 commits intomainfrom
feat/perses
Open

GIE-394: Render Perses charts for observability data#112
eyevana wants to merge 4 commits intomainfrom
feat/perses

Conversation

@eyevana
Copy link
Contributor

@eyevana eyevana commented Feb 3, 2026

Description

This PR adds support for rendering Perses visualization charts (TimeSeriesChart and PieChart) directly in the chat interface. When the AI generates NGUI widget configurations with Perses components, the system now renders interactive Prometheus-backed charts instead of static content.

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📝 Documentation update
  • 🎨 UI/UX improvement
  • ♻️ Code refactoring (no functional changes)
  • ⚡ Performance improvement
  • 🧪 Test updates

Related Issues

Fixes #

Changes Made

New Files

Perses Components (src/components/perses/)

  • PersesTimeSeries.tsx - Time series chart component for range queries (stacked area chart)
  • PersesPieChart.tsx - Pie chart component for instant queries
  • PersesWidgetWrapper.tsx - Provider wrapper that sets up Perses context (theme, plugins, datasource, time range)
  • componentRegistry.ts - Lazy-loaded component registry with type guards for Perses components
  • pluginsLoader.ts - Configures Perses plugin system with all required chart plugins
  • queryClient.ts - React Query client configuration for Perses
  • ocpDatasourceApi.ts - Datasource API implementation for OpenShift Prometheus proxy
  • cachedDatasource.ts - Caching layer for datasource API

Types and Hooks

  • src/types/perses.ts - TypeScript type definitions for Perses props and component names
  • src/hooks/useTimeRange.ts - Hook to convert start/end/duration into Perses TimeRangeValue

Modified Files

Widget Rendering

  • src/components/artifacts/WidgetRenderer.tsx

    • Added Perses component detection using isPersesComponent() type guard
    • Extracts query parameters from tool call arguments
    • Renders Perses components with <Suspense> fallback
    • Falls back to DynamicComponent for non-Perses widgets
  • src/components/artifacts/ArtifactRenderer.tsx

    • Now passes toolCalls prop to WidgetRenderer for query parameter extraction

Chat Integration

  • src/components/Chat/AIMessage.tsx
    • Passes toolCalls to ArtifactRenderer
    • Only renders artifacts when not streaming (prevents partial renders)

Configuration

  • backend/lightspeed-stack/ngui_openshift_mcp_config.yaml
    • Added execute_range_query mapping to PersesTimeSeries
    • Added execute_instant_query mapping to PersesPieChart

Dependencies Added (package.json)

  • @perses-dev/* packages (components, core, dashboards, plugin-system, prometheus-plugin, chart plugins)
  • @tanstack/react-query - For Perses data fetching
  • @mui/material, @emotion/react, @emotion/styled - Required by Perses UI
  • echarts - Charting library used by Perses
  • Supporting utilities: date-fns-tz, immer, lodash, lru-cache, use-resize-observer

Testing Done

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • Tested on different browsers/devices (if applicable)

Test Details:

  • Verify TimeSeriesChart renders for execute_range_query tool results
  • Verify PieChart renders for execute_instant_query tool results
  • Confirm charts fetch data from Prometheus proxy endpoint
  • Test relative time ranges (duration only) and absolute time ranges (start/end)
  • Verify lazy loading - Perses bundle only loads when chart is rendered
  • Test fallback to DynamicComponent for non-Perses NGUI widgets
  • Confirm no chart flicker during streaming (artifacts only render after stream completes)

Screenshots/Videos

Click to expand

Definition of Done (DOD)

Code Quality

  • Code follows project style guidelines and conventions
  • Code has been self-reviewed for logic, readability, and best practices
  • No debugging code (console.logs, commented code, etc.) left behind
  • No linter errors or warnings introduced
  • Code is properly commented where necessary

Testing

  • Unit tests added/updated and passing
  • Integration tests added/updated (if applicable)
  • Manual testing completed successfully
  • Edge cases and error scenarios tested
  • No existing tests broken by changes

Documentation

  • Code documentation updated (JSDoc, inline comments)
  • README updated (if applicable)
  • User-facing documentation updated (if applicable)
  • CHANGELOG updated (if maintained)

Review & Quality

  • PR description is clear and complete
  • All related issues are linked
  • Breaking changes are clearly documented
  • Security implications considered and addressed
  • Performance impact assessed
  • Accessibility requirements met (if UI changes)

Pre-Merge

  • All CI/CD checks passing
  • At least one approval from code owner/reviewer
  • All review comments addressed or resolved
  • Branch is up to date with target branch
  • No merge conflicts

Additional Notes

This is not the final solution. When Libor returns from PTO, we'll get the arguments we need from the previous tool call in the NGUI generate_ui response. I won't need to pass tool calls down to the widgets like I've done here. See thread.

Reviewer Guidance


@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 3, 2026
@openshift-ci
Copy link

openshift-ci bot commented Feb 3, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci
Copy link

openshift-ci bot commented Feb 3, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: eyevana

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 3, 2026
@eyevana eyevana changed the title Feat/perses GIE-394: Render Perses charts fro observability data Feb 3, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Feb 3, 2026
@openshift-ci-robot
Copy link

openshift-ci-robot commented Feb 3, 2026

@eyevana: This pull request references GIE-394 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Description

This PR adds support for rendering Perses visualization charts (TimeSeriesChart and PieChart) directly in the chat interface. When the AI generates NGUI widget configurations with Perses components, the system now renders interactive Prometheus-backed charts instead of static content.

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📝 Documentation update
  • 🎨 UI/UX improvement
  • ♻️ Code refactoring (no functional changes)
  • ⚡ Performance improvement
  • 🧪 Test updates

Related Issues

Fixes #

Changes Made

New Files

Perses Components (src/components/perses/)

  • PersesTimeSeries.tsx - Time series chart component for range queries (stacked area chart)
  • PersesPieChart.tsx - Pie chart component for instant queries
  • PersesWidgetWrapper.tsx - Provider wrapper that sets up Perses context (theme, plugins, datasource, time range)
  • componentRegistry.ts - Lazy-loaded component registry with type guards for Perses components
  • pluginsLoader.ts - Configures Perses plugin system with all required chart plugins
  • queryClient.ts - React Query client configuration for Perses
  • ocpDatasourceApi.ts - Datasource API implementation for OpenShift Prometheus proxy
  • cachedDatasource.ts - Caching layer for datasource API

Types and Hooks

  • src/types/perses.ts - TypeScript type definitions for Perses props and component names
  • src/hooks/useTimeRange.ts - Hook to convert start/end/duration into Perses TimeRangeValue

Modified Files

Widget Rendering

  • src/components/artifacts/WidgetRenderer.tsx

  • Added Perses component detection using isPersesComponent() type guard

  • Extracts query parameters from tool call arguments

  • Renders Perses components with <Suspense> fallback

  • Falls back to DynamicComponent for non-Perses widgets

  • src/components/artifacts/ArtifactRenderer.tsx

  • Now passes toolCalls prop to WidgetRenderer for query parameter extraction

Chat Integration

  • src/components/Chat/AIMessage.tsx
  • Passes toolCalls to ArtifactRenderer
  • Only renders artifacts when not streaming (prevents partial renders)

Configuration

  • backend/lightspeed-stack/ngui_openshift_mcp_config.yaml
  • Added execute_range_query mapping to PersesTimeSeries
  • Added execute_instant_query mapping to PersesPieChart

Dependencies Added (package.json)

  • @perses-dev/* packages (components, core, dashboards, plugin-system, prometheus-plugin, chart plugins)
  • @tanstack/react-query - For Perses data fetching
  • @mui/material, @emotion/react, @emotion/styled - Required by Perses UI
  • echarts - Charting library used by Perses
  • Supporting utilities: date-fns-tz, immer, lodash, lru-cache, use-resize-observer

Testing Done

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • Tested on different browsers/devices (if applicable)

Test Details:

  • Verify TimeSeriesChart renders for execute_range_query tool results
  • Verify PieChart renders for execute_instant_query tool results
  • Confirm charts fetch data from Prometheus proxy endpoint
  • Test relative time ranges (duration only) and absolute time ranges (start/end)
  • Verify lazy loading - Perses bundle only loads when chart is rendered
  • Test fallback to DynamicComponent for non-Perses NGUI widgets
  • Confirm no chart flicker during streaming (artifacts only render after stream completes)

Screenshots/Videos

Click to expand

Definition of Done (DOD)

Code Quality

  • Code follows project style guidelines and conventions
  • Code has been self-reviewed for logic, readability, and best practices
  • No debugging code (console.logs, commented code, etc.) left behind
  • No linter errors or warnings introduced
  • Code is properly commented where necessary

Testing

  • Unit tests added/updated and passing
  • Integration tests added/updated (if applicable)
  • Manual testing completed successfully
  • Edge cases and error scenarios tested
  • No existing tests broken by changes

Documentation

  • Code documentation updated (JSDoc, inline comments)
  • README updated (if applicable)
  • User-facing documentation updated (if applicable)
  • CHANGELOG updated (if maintained)

Review & Quality

  • PR description is clear and complete
  • All related issues are linked
  • Breaking changes are clearly documented
  • Security implications considered and addressed
  • Performance impact assessed
  • Accessibility requirements met (if UI changes)

Pre-Merge

  • All CI/CD checks passing
  • At least one approval from code owner/reviewer
  • All review comments addressed or resolved
  • Branch is up to date with target branch
  • No merge conflicts

Additional Notes

Reviewer Guidance


Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@eyevana eyevana changed the title GIE-394: Render Perses charts fro observability data GIE-394: Render Perses charts for observability data Feb 3, 2026
@eyevana eyevana marked this pull request as ready for review February 3, 2026 17:42
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 3, 2026
@eyevana eyevana requested a review from spadgett February 3, 2026 18:52
@openshift-ci-robot
Copy link

openshift-ci-robot commented Feb 3, 2026

@eyevana: This pull request references GIE-394 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Description

This PR adds support for rendering Perses visualization charts (TimeSeriesChart and PieChart) directly in the chat interface. When the AI generates NGUI widget configurations with Perses components, the system now renders interactive Prometheus-backed charts instead of static content.

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📝 Documentation update
  • 🎨 UI/UX improvement
  • ♻️ Code refactoring (no functional changes)
  • ⚡ Performance improvement
  • 🧪 Test updates

Related Issues

Fixes #

Changes Made

New Files

Perses Components (src/components/perses/)

  • PersesTimeSeries.tsx - Time series chart component for range queries (stacked area chart)
  • PersesPieChart.tsx - Pie chart component for instant queries
  • PersesWidgetWrapper.tsx - Provider wrapper that sets up Perses context (theme, plugins, datasource, time range)
  • componentRegistry.ts - Lazy-loaded component registry with type guards for Perses components
  • pluginsLoader.ts - Configures Perses plugin system with all required chart plugins
  • queryClient.ts - React Query client configuration for Perses
  • ocpDatasourceApi.ts - Datasource API implementation for OpenShift Prometheus proxy
  • cachedDatasource.ts - Caching layer for datasource API

Types and Hooks

  • src/types/perses.ts - TypeScript type definitions for Perses props and component names
  • src/hooks/useTimeRange.ts - Hook to convert start/end/duration into Perses TimeRangeValue

Modified Files

Widget Rendering

  • src/components/artifacts/WidgetRenderer.tsx

  • Added Perses component detection using isPersesComponent() type guard

  • Extracts query parameters from tool call arguments

  • Renders Perses components with <Suspense> fallback

  • Falls back to DynamicComponent for non-Perses widgets

  • src/components/artifacts/ArtifactRenderer.tsx

  • Now passes toolCalls prop to WidgetRenderer for query parameter extraction

Chat Integration

  • src/components/Chat/AIMessage.tsx
  • Passes toolCalls to ArtifactRenderer
  • Only renders artifacts when not streaming (prevents partial renders)

Configuration

  • backend/lightspeed-stack/ngui_openshift_mcp_config.yaml
  • Added execute_range_query mapping to PersesTimeSeries
  • Added execute_instant_query mapping to PersesPieChart

Dependencies Added (package.json)

  • @perses-dev/* packages (components, core, dashboards, plugin-system, prometheus-plugin, chart plugins)
  • @tanstack/react-query - For Perses data fetching
  • @mui/material, @emotion/react, @emotion/styled - Required by Perses UI
  • echarts - Charting library used by Perses
  • Supporting utilities: date-fns-tz, immer, lodash, lru-cache, use-resize-observer

Testing Done

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • Tested on different browsers/devices (if applicable)

Test Details:

  • Verify TimeSeriesChart renders for execute_range_query tool results
  • Verify PieChart renders for execute_instant_query tool results
  • Confirm charts fetch data from Prometheus proxy endpoint
  • Test relative time ranges (duration only) and absolute time ranges (start/end)
  • Verify lazy loading - Perses bundle only loads when chart is rendered
  • Test fallback to DynamicComponent for non-Perses NGUI widgets
  • Confirm no chart flicker during streaming (artifacts only render after stream completes)

Screenshots/Videos

Click to expand

Definition of Done (DOD)

Code Quality

  • Code follows project style guidelines and conventions
  • Code has been self-reviewed for logic, readability, and best practices
  • No debugging code (console.logs, commented code, etc.) left behind
  • No linter errors or warnings introduced
  • Code is properly commented where necessary

Testing

  • Unit tests added/updated and passing
  • Integration tests added/updated (if applicable)
  • Manual testing completed successfully
  • Edge cases and error scenarios tested
  • No existing tests broken by changes

Documentation

  • Code documentation updated (JSDoc, inline comments)
  • README updated (if applicable)
  • User-facing documentation updated (if applicable)
  • CHANGELOG updated (if maintained)

Review & Quality

  • PR description is clear and complete
  • All related issues are linked
  • Breaking changes are clearly documented
  • Security implications considered and addressed
  • Performance impact assessed
  • Accessibility requirements met (if UI changes)

Pre-Merge

  • All CI/CD checks passing
  • At least one approval from code owner/reviewer
  • All review comments addressed or resolved
  • Branch is up to date with target branch
  • No merge conflicts

Additional Notes

This is not the final solution. When Libor returns from PTO, we'll get the arguments we need from the previous tool call in the NGUI generate_ui response. I won't need to pass tool calls down to the widgets like I've done here. See thread.

Reviewer Guidance


Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Feb 3, 2026

@eyevana: This pull request references GIE-394 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Description

This PR adds support for rendering Perses visualization charts (TimeSeriesChart and PieChart) directly in the chat interface. When the AI generates NGUI widget configurations with Perses components, the system now renders interactive Prometheus-backed charts instead of static content.

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📝 Documentation update
  • 🎨 UI/UX improvement
  • ♻️ Code refactoring (no functional changes)
  • ⚡ Performance improvement
  • 🧪 Test updates

Related Issues

Fixes #

Changes Made

New Files

Perses Components (src/components/perses/)

  • PersesTimeSeries.tsx - Time series chart component for range queries (stacked area chart)
  • PersesPieChart.tsx - Pie chart component for instant queries
  • PersesWidgetWrapper.tsx - Provider wrapper that sets up Perses context (theme, plugins, datasource, time range)
  • componentRegistry.ts - Lazy-loaded component registry with type guards for Perses components
  • pluginsLoader.ts - Configures Perses plugin system with all required chart plugins
  • queryClient.ts - React Query client configuration for Perses
  • ocpDatasourceApi.ts - Datasource API implementation for OpenShift Prometheus proxy
  • cachedDatasource.ts - Caching layer for datasource API

Types and Hooks

  • src/types/perses.ts - TypeScript type definitions for Perses props and component names
  • src/hooks/useTimeRange.ts - Hook to convert start/end/duration into Perses TimeRangeValue

Modified Files

Widget Rendering

  • src/components/artifacts/WidgetRenderer.tsx

  • Added Perses component detection using isPersesComponent() type guard

  • Extracts query parameters from tool call arguments

  • Renders Perses components with <Suspense> fallback

  • Falls back to DynamicComponent for non-Perses widgets

  • src/components/artifacts/ArtifactRenderer.tsx

  • Now passes toolCalls prop to WidgetRenderer for query parameter extraction

Chat Integration

  • src/components/Chat/AIMessage.tsx
  • Passes toolCalls to ArtifactRenderer
  • Only renders artifacts when not streaming (prevents partial renders)

Configuration

  • backend/lightspeed-stack/ngui_openshift_mcp_config.yaml
  • Added execute_range_query mapping to PersesTimeSeries
  • Added execute_instant_query mapping to PersesPieChart

Dependencies Added (package.json)

  • @perses-dev/* packages (components, core, dashboards, plugin-system, prometheus-plugin, chart plugins)
  • @tanstack/react-query - For Perses data fetching
  • @mui/material, @emotion/react, @emotion/styled - Required by Perses UI
  • echarts - Charting library used by Perses
  • Supporting utilities: date-fns-tz, immer, lodash, lru-cache, use-resize-observer

Testing Done

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • Tested on different browsers/devices (if applicable)

Test Details:

  • Verify TimeSeriesChart renders for execute_range_query tool results
  • Verify PieChart renders for execute_instant_query tool results
  • Confirm charts fetch data from Prometheus proxy endpoint
  • Test relative time ranges (duration only) and absolute time ranges (start/end)
  • Verify lazy loading - Perses bundle only loads when chart is rendered
  • Test fallback to DynamicComponent for non-Perses NGUI widgets
  • Confirm no chart flicker during streaming (artifacts only render after stream completes)

Screenshots/Videos

Click to expand

Definition of Done (DOD)

Code Quality

  • Code follows project style guidelines and conventions
  • Code has been self-reviewed for logic, readability, and best practices
  • No debugging code (console.logs, commented code, etc.) left behind
  • No linter errors or warnings introduced
  • Code is properly commented where necessary

Testing

  • Unit tests added/updated and passing
  • Integration tests added/updated (if applicable)
  • Manual testing completed successfully
  • Edge cases and error scenarios tested
  • No existing tests broken by changes

Documentation

  • Code documentation updated (JSDoc, inline comments)
  • README updated (if applicable)
  • User-facing documentation updated (if applicable)
  • CHANGELOG updated (if maintained)

Review & Quality

  • PR description is clear and complete
  • All related issues are linked
  • Breaking changes are clearly documented
  • Security implications considered and addressed
  • Performance impact assessed
  • Accessibility requirements met (if UI changes)

Pre-Merge

  • All CI/CD checks passing
  • At least one approval from code owner/reviewer
  • All review comments addressed or resolved
  • Branch is up to date with target branch
  • No merge conflicts

Additional Notes

This is not the final solution. When Libor returns from PTO, we'll get the arguments we need from the previous tool call in the NGUI generate_ui response. I won't need to pass tool calls down to the widgets like I've done here. See thread.

Reviewer Guidance


Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@eyevana eyevana requested a review from iNecas February 4, 2026 14:27
return undefined;
}

const matchingCalls = toolCalls.filter((toolCall) => toolCall.name === inputDataType);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would happen if multiple execute_range_query queries happened during the same call?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should pull the args from the last execute_range_query tool call in the list.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a plan to improve this? It's not impossible for multiple relevant queries could be made as part of the same request. Not a blocker, but would be good to have a plan there.

@openshift-ci
Copy link

openshift-ci bot commented Feb 5, 2026

@eyevana: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 7, 2026
@openshift-merge-robot
Copy link

PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants