@grafana/assistant 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -84,6 +84,48 @@ openAssistant({
84
84
  });
85
85
  ```
86
86
 
87
+ ### Providing Page-Specific Context
88
+
89
+ You can register context items that are automatically included when the assistant is opened on pages matching specific URL patterns. The `providePageContext` function works like `useState` - it returns a setter function that allows you to update the context dynamically:
90
+
91
+ ```typescript
92
+ import { providePageContext, createContext } from '@grafana/assistant';
93
+
94
+ // Create initial context for dashboard pages
95
+ const dashboardContext = createContext('structured', {
96
+ data: {
97
+ name: 'Dashboard Context',
98
+ pageType: 'dashboard',
99
+ capabilities: ['view', 'edit', 'share'],
100
+ help: 'Use the assistant to analyze dashboard data, create queries, or troubleshoot issues.'
101
+ }
102
+ });
103
+
104
+ // Register context for all dashboard pages and get a setter function
105
+ const setContext = providePageContext('/d/*', [dashboardContext]);
106
+
107
+ // Later, dynamically update the context based on user interactions or data changes
108
+ setContext([
109
+ dashboardContext,
110
+ createContext('structured', {
111
+ data: {
112
+ name: 'Panel Context',
113
+ selectedPanel: 'cpu-usage-panel',
114
+ panelType: 'graph'
115
+ }
116
+ })
117
+ ]);
118
+
119
+ // The context will automatically be included when openAssistant is called from dashboard pages
120
+ openAssistant({
121
+ prompt: 'Help me analyze this dashboard'
122
+ // Current context is automatically included
123
+ });
124
+
125
+ // Clean up when no longer needed
126
+ setContext.unregister();
127
+ ```
128
+
87
129
  ### Creating Context Items
88
130
 
89
131
  The `createContext` function allows you to create structured context items that provide the assistant with additional information about your Grafana resources.
@@ -230,6 +272,36 @@ Creates a context item that can be passed to the assistant to provide additional
230
272
 
231
273
  **Returns:** A `ChatContextItem` that can be passed to `openAssistant`
232
274
 
275
+ #### `providePageContext(urlPattern: string | RegExp, initialContext: ChatContextItem[]): ((context: ChatContextItem[]) => void) & { unregister: () => void }`
276
+
277
+ Registers context items for specific pages based on URL patterns. Returns a setter function to update the context dynamically, similar to `useState`. The context will be automatically included when the assistant is opened on pages matching the pattern.
278
+
279
+ **Parameters:**
280
+ - `urlPattern` - URL pattern (string with wildcards or RegExp) to match against page URLs
281
+ - String patterns support `*` (match any characters) and `**` (match any path segments)
282
+ - RegExp patterns provide full regex matching capabilities
283
+ - `initialContext` - Initial array of `ChatContextItem` to provide when the pattern matches
284
+
285
+ **Returns:** A setter function to update the context, with an `unregister` method attached for cleanup
286
+
287
+ **Examples:**
288
+ ```typescript
289
+ // String patterns - returns setter function
290
+ const setDashboardContext = providePageContext('/d/*', initialContext); // Match any dashboard
291
+ const setExploreContext = providePageContext('/explore**', initialContext); // Match explore and subpaths
292
+
293
+ // RegExp patterns
294
+ const setSpecificContext = providePageContext(/^\/d\/[a-zA-Z0-9]+$/, initialContext); // Match specific dashboard format
295
+
296
+ // Update context dynamically
297
+ setDashboardContext([...newContext]);
298
+
299
+ // Cleanup when done
300
+ setDashboardContext.unregister();
301
+ ```
302
+
303
+
304
+
233
305
  ### Sidebar Types
234
306
 
235
307
  #### `OpenAssistantProps`
@@ -238,11 +310,16 @@ Creates a context item that can be passed to the assistant to provide additional
238
310
  type OpenAssistantProps = {
239
311
  prompt?: string;
240
312
  context?: ChatContextItem[];
313
+ includePageContext?: boolean;
241
314
  };
242
315
  ```
243
316
 
244
317
  Configuration object for opening the assistant.
245
318
 
319
+ - `prompt` - Optional initial prompt to display
320
+ - `context` - Optional context items to provide
321
+ - `includePageContext` - Whether to automatically include page context for the current URL (defaults to true)
322
+
246
323
  #### `ChatContextItem`
247
324
 
248
325
  ```typescript
@@ -254,6 +331,8 @@ type ChatContextItem = {
254
331
 
255
332
  A context item that provides structured information to the assistant.
256
333
 
334
+
335
+
257
336
  ### Context Types
258
337
 
259
338
  #### Datasource Context Parameters
@@ -4,4 +4,5 @@ export * from './dashboard';
4
4
  export * from './datasource';
5
5
  export * from './factory';
6
6
  export * from './label';
7
+ export * from './page';
7
8
  export * from './types';
@@ -0,0 +1,29 @@
1
+ import { ChatContextItem } from './types';
2
+ export interface PageContextRegistration {
3
+ id: string;
4
+ urlPattern: string | RegExp;
5
+ context: ChatContextItem[];
6
+ }
7
+ /**
8
+ * Registers context items for specific pages based on URL patterns.
9
+ * Returns a setter function to update the context dynamically, similar to useState.
10
+ *
11
+ * If a registration with the same URL pattern already exists, it will be replaced.
12
+ *
13
+ * @param urlPattern - URL pattern (string or RegExp) to match against page URLs
14
+ * @param initialContext - Initial array of ChatContextItem to provide when the pattern matches
15
+ * @returns A setter function to update the context, with an unregister method attached
16
+ */
17
+ export declare function providePageContext(urlPattern: string | RegExp, initialContext: ChatContextItem[]): ((context: ChatContextItem[]) => void) & {
18
+ unregister: () => void;
19
+ };
20
+ /**
21
+ * React hook for providing page context that automatically cleans up on unmount.
22
+ * This is the recommended way to use page context in React components.
23
+ *
24
+ * @param urlPattern - URL pattern (string or RegExp) to match against page URLs
25
+ * @param initialContext - Initial array of ChatContextItem to provide when the pattern matches
26
+ * @returns A setter function to update the context
27
+ */
28
+ export declare function useProvidePageContext(urlPattern: string | RegExp, initialContext?: ChatContextItem[]): (context: ChatContextItem[]) => void;
29
+ export declare function usePageContext(): ChatContextItem[];
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { createContext, DashboardNodeData, DatasourceNodeData, FolderNodeData, ItemDataType, LabelNameNodeData, LabelValueNodeData, StructuredNodeData, TreeNode, } from './context/index';
1
+ export { createContext, DashboardNodeData, DatasourceNodeData, FolderNodeData, ItemDataType, LabelNameNodeData, LabelValueNodeData, StructuredNodeData, TreeNode, providePageContext, PageContextRegistration, usePageContext, } from './context/index';
2
2
  export * from './functions';
3
3
  export * from './hook';
4
4
  export * from './plugin';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- (()=>{"use strict";var e,a={d:(e,t)=>{for(var s in t)a.o(t,s)&&!a.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},o:(e,a)=>Object.prototype.hasOwnProperty.call(e,a),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};function s(e){let a=5381;for(let t=0;t<e.length;t++)a=(a<<5)+a+e.charCodeAt(t);return(a>>>0).toString(16)}a.r(t),a.d(t,{CALLBACK_EXTENSION_POINT:()=>p,DashboardNodeData:()=>d,DatasourceNodeData:()=>i,FolderNodeData:()=>n,ItemDataType:()=>e,LabelNameNodeData:()=>l,LabelValueNodeData:()=>u,StructuredNodeData:()=>o,closeAssistant:()=>x,createContext:()=>h,getExposeAssistantFunctionsConfig:()=>m,isAssistantAvailable:()=>U,newFunctionNamespace:()=>f,openAssistant:()=>D,useAssistant:()=>w}),function(e){e.Unknown="unknown",e.Datasource="datasource",e.LabelName="label_name",e.LabelValue="label_value",e.Dashboard="dashboard",e.DashboardFolder="dashboard_folder",e.Structured="structured"}(e||(e={}));class r{constructor(e){this.params=e,this.id=s(e.id)}formatForLLM(a){return{type:e.Unknown,codeElementIds:a,data:{name:this.params.text}}}}class o{constructor(e){this.params=e,this.id=s(JSON.stringify(e.data))}formatForLLM(a){return{type:e.Structured,codeElementIds:a,data:this.params.data}}}class d extends r{constructor(e){super({...e,id:e.dashboardUid}),this.dashboardUid=e.dashboardUid,this.dashboardTitle=e.dashboardTitle,this.folderUid=e.folderUid,this.folderTitle=e.folderTitle}formatForLLM(a){return{type:e.Dashboard,codeElementIds:a,data:{name:this.dashboardTitle,dashboardUid:this.dashboardUid,dashboardTitle:this.dashboardTitle,folderUid:this.folderUid,folderTitle:this.folderTitle}}}}class n extends r{constructor(e){super({...e,id:e.folderUid}),this.folderUid=e.folderUid,this.folderTitle=e.folderTitle}formatForLLM(a){return{type:e.DashboardFolder,codeElementIds:a,data:{name:this.folderTitle,folderUid:this.folderUid,folderTitle:this.folderTitle}}}}class i extends r{constructor(e){super({...e,id:e.datasourceUid}),this.datasourceUid=e.datasourceUid,this.datasourceType=e.datasourceType,this.datasourceName=e.datasourceName}formatForLLM(a){return{type:e.Datasource,codeElementIds:a,data:{name:this.datasourceName,uid:this.datasourceUid,type:this.datasourceType}}}}class l extends r{constructor(e){super({...e,id:`${e.datasourceUid}-${e.labelName}`}),this.datasourceUid=e.datasourceUid,this.datasourceType=e.datasourceType,this.labelName=e.labelName}formatForLLM(a){return{type:e.LabelName,codeElementIds:a,data:{name:this.labelName,datasourceUid:this.datasourceUid,datasourceType:this.datasourceType,labelName:this.labelName}}}}class u extends r{constructor(e){super({...e,id:`${e.datasourceUid}-${e.labelName}-${e.labelValue}`}),this.datasourceUid=e.datasourceUid,this.datasourceType=e.datasourceType,this.labelName=e.labelName,this.labelValue=e.labelValue}formatForLLM(a){return{type:e.LabelValue,codeElementIds:a,data:{name:this.labelValue,datasourceUid:this.datasourceUid,datasourceType:this.datasourceType,labelName:this.labelName,labelValue:this.labelValue}}}}const c={[e.Datasource]:"database",[e.LabelName]:"database",[e.LabelValue]:"database",[e.Dashboard]:"dashboard",[e.DashboardFolder]:"folder",[e.Unknown]:"circle-mono",[e.Structured]:"gf-grid"};function b(a,t){return a===e.Datasource?t.datasourceName:a===e.LabelName?t.labelName:a===e.LabelValue?t.labelValue:a===e.Dashboard?t.dashboardTitle:a===e.DashboardFolder?t.folderTitle:a===e.Structured?t.data.name:"Given Context"}function h(e,a){var t,s;const h=function(e,a){switch(e){case"datasource":return new i(a);case"label_name":return new l(a);case"label_value":return new u(a);case"dashboard":return new d(a);case"dashboard_folder":return new n(a);case"structured":return new o(a);case"unknown":return new r(a);default:return console.error(`Unknown context type: ${e}`),new r(a)}}(e,a);return{node:{id:h.id,name:null!==(t=a.title)&&void 0!==t?t:b(e,a),icon:null!==(s=a.icon)&&void 0!==s?s:c[e],navigable:!1,selectable:!0,data:h},occurrences:[]}}const p="grafana-assistant-app/callback/v0-alpha";function f(e,a){return{namespace:e,functions:a}}function m(e){return{title:"callback",targets:[p],fn:()=>e.map(e=>({namespace:e.namespace,functions:e.functions}))}}const y=require("react"),T=require("@grafana/runtime"),N=require("rxjs");function U(){return(0,T.getObservablePluginLinks)({extensionPointId:"grafana/extension-sidebar/v0-alpha"}).pipe((0,N.map)(e=>e.some(e=>"grafana-assistant-app"===e.pluginId&&"Grafana Assistant"===e.title)))}const L=require("@grafana/data");class g extends L.BusEventWithPayload{}g.type="open-extension-sidebar";class v extends L.BusEventBase{}function D(e){!function(e,a,t){const s=new g({pluginId:"grafana-assistant-app",componentTitle:"Grafana Assistant",props:t});(0,T.getAppEvents)().publish(s)}(0,0,{initialPrompt:e.prompt,initialContext:e.context})}function x(){!function(){const e=new v;(0,T.getAppEvents)().publish(e)}()}function w(){const[e,a]=(0,y.useState)(!1);return(0,y.useEffect)(()=>{const e=U().subscribe(e=>a(e));return()=>{e.unsubscribe()}},[]),[e,e?D:void 0,e?x:void 0]}v.type="close-extension-sidebar",module.exports=t})();
1
+ (()=>{"use strict";var e,t={d:(e,a)=>{for(var n in a)t.o(a,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},a={};function n(e){let t=5381;for(let a=0;a<e.length;a++)t=(t<<5)+t+e.charCodeAt(a);return(t>>>0).toString(16)}t.r(a),t.d(a,{CALLBACK_EXTENSION_POINT:()=>N,DashboardNodeData:()=>o,DatasourceNodeData:()=>i,FolderNodeData:()=>d,ItemDataType:()=>e,LabelNameNodeData:()=>l,LabelValueNodeData:()=>c,StructuredNodeData:()=>r,closeAssistant:()=>V,createContext:()=>f,getExposeAssistantFunctionsConfig:()=>D,isAssistantAvailable:()=>S,newFunctionNamespace:()=>U,openAssistant:()=>A,providePageContext:()=>y,useAssistant:()=>M,usePageContext:()=>x}),function(e){e.Unknown="unknown",e.Datasource="datasource",e.LabelName="label_name",e.LabelValue="label_value",e.Dashboard="dashboard",e.DashboardFolder="dashboard_folder",e.Structured="structured"}(e||(e={}));class s{constructor(e){this.params=e,this.id=n(e.id)}formatForLLM(t){return{type:e.Unknown,codeElementIds:t,data:{name:this.params.text}}}}class r{constructor(e){this.params=e,this.id=n(JSON.stringify(e.data))}formatForLLM(t){return{type:e.Structured,codeElementIds:t,data:this.params.data}}}class o extends s{constructor(e){super({...e,id:e.dashboardUid}),this.dashboardUid=e.dashboardUid,this.dashboardTitle=e.dashboardTitle,this.folderUid=e.folderUid,this.folderTitle=e.folderTitle}formatForLLM(t){return{type:e.Dashboard,codeElementIds:t,data:{name:this.dashboardTitle,dashboardUid:this.dashboardUid,dashboardTitle:this.dashboardTitle,folderUid:this.folderUid,folderTitle:this.folderTitle}}}}class d extends s{constructor(e){super({...e,id:e.folderUid}),this.folderUid=e.folderUid,this.folderTitle=e.folderTitle}formatForLLM(t){return{type:e.DashboardFolder,codeElementIds:t,data:{name:this.folderTitle,folderUid:this.folderUid,folderTitle:this.folderTitle}}}}class i extends s{constructor(e){super({...e,id:e.datasourceUid}),this.datasourceUid=e.datasourceUid,this.datasourceType=e.datasourceType,this.datasourceName=e.datasourceName}formatForLLM(t){return{type:e.Datasource,codeElementIds:t,data:{name:this.datasourceName,uid:this.datasourceUid,type:this.datasourceType}}}}class l extends s{constructor(e){super({...e,id:`${e.datasourceUid}-${e.labelName}`}),this.datasourceUid=e.datasourceUid,this.datasourceType=e.datasourceType,this.labelName=e.labelName}formatForLLM(t){return{type:e.LabelName,codeElementIds:t,data:{name:this.labelName,datasourceUid:this.datasourceUid,datasourceType:this.datasourceType,labelName:this.labelName}}}}class c extends s{constructor(e){super({...e,id:`${e.datasourceUid}-${e.labelName}-${e.labelValue}`}),this.datasourceUid=e.datasourceUid,this.datasourceType=e.datasourceType,this.labelName=e.labelName,this.labelValue=e.labelValue}formatForLLM(t){return{type:e.LabelValue,codeElementIds:t,data:{name:this.labelValue,datasourceUid:this.datasourceUid,datasourceType:this.datasourceType,labelName:this.labelName,labelValue:this.labelValue}}}}const u={[e.Datasource]:"database",[e.LabelName]:"database",[e.LabelValue]:"database",[e.Dashboard]:"dashboard",[e.DashboardFolder]:"folder",[e.Unknown]:"circle-mono",[e.Structured]:"gf-grid"};function p(t,a){return t===e.Datasource?a.datasourceName:t===e.LabelName?a.labelName:t===e.LabelValue?a.labelValue:t===e.Dashboard?a.dashboardTitle:t===e.DashboardFolder?a.folderTitle:t===e.Structured?a.data.name:"Given Context"}function f(e,t){var a,n;const f=function(e,t){switch(e){case"datasource":return new i(t);case"label_name":return new l(t);case"label_value":return new c(t);case"dashboard":return new o(t);case"dashboard_folder":return new d(t);case"structured":return new r(t);case"unknown":return new s(t);default:return console.error(`Unknown context type: ${e}`),new s(t)}}(e,t);return{node:{id:f.id,name:null!==(a=t.title)&&void 0!==a?a:p(e,t),icon:null!==(n=t.icon)&&void 0!==n?n:u[e],navigable:!1,selectable:!0,data:f},occurrences:[]}}const h=require("@grafana/runtime"),b=require("react"),m=[],v="grafana-assistant:page-context-sync",w="grafana-assistant:page-context-update",g="grafana-assistant:page-context-remove",L="grafana-assistant:location-changed";let E=!1;function y(e,t){const a=m.findIndex((t=>{return a=t.urlPattern,n=e,"string"==typeof a&&"string"==typeof n?a===n:a instanceof RegExp&&n instanceof RegExp&&a.source===n.source&&a.flags===n.flags;var a,n}));let n;-1!==a?(n=m[a],n.context=[...t]):(n={id:`page-context-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,urlPattern:e,context:[...t]},m.push(n)),window.dispatchEvent(new CustomEvent(w,{detail:n})),window.dispatchEvent(new CustomEvent(v,{detail:{registry:m}}));const s=e=>{const t=m.findIndex((e=>e.id===n.id));-1!==t&&(m[t].context=[...e],window.dispatchEvent(new CustomEvent(w,{detail:m[t]})))};return s.unregister=()=>{const e=m.findIndex((e=>e.id===n.id));-1!==e&&(m.splice(e,1),window.dispatchEvent(new CustomEvent(g,{detail:{id:n.id}})))},s}function x(){const[e,t]=(0,b.useState)([]),a=(0,h.useLocationService)(),n=(0,b.useRef)("");return(0,b.useEffect)((()=>{const e=()=>{const e=function(e,t){if(!e)return[];const a=[];for(const n of t)T(e,n.urlPattern)&&a.push(...n.context);return a}(a.getLocation().pathname,m);t(e)},s=()=>{e()},r=t=>{var n;const s=null===(n=t.detail)||void 0===n?void 0:n.pathname;s&&s===a.getLocation().pathname&&e()},o=a.getLocationObservable().subscribe((t=>{const a=t.pathname;a!==n.current&&(n.current=a,function(e){window.dispatchEvent(new CustomEvent(L,{detail:{pathname:e}}))}(a),e())}));return e(),window.addEventListener(v,s),window.addEventListener(w,s),window.addEventListener(g,s),window.addEventListener(L,r),()=>{o.unsubscribe(),window.removeEventListener(v,s),window.removeEventListener(w,s),window.removeEventListener(g,s),window.removeEventListener(L,r)}}),[a]),e}function T(e,t){if(t instanceof RegExp)return t.test(e);if("string"==typeof t){const a=t.replace(/\*\*/g,".*").replace(/\*/g,"[^/]*").replace(/\?/g,".");return new RegExp(`^${a}$`).test(e)}return!1}E||(window.addEventListener(v,(e=>{var t;const a=null===(t=e.detail)||void 0===t?void 0:t.registry;if(a){const e=new Set(m.map((e=>e.id))),t=a.filter((t=>!e.has(t.id)));m.push(...t)}})),window.addEventListener(w,(e=>{const t=e.detail;if(t){const e=m.findIndex((e=>e.id===t.id));-1!==e?m[e]=t:m.push(t)}})),window.addEventListener(g,(e=>{var t;const a=null===(t=e.detail)||void 0===t?void 0:t.id;if(a){const e=m.findIndex((e=>e.id===a));-1!==e&&m.splice(e,1)}})),E=!0);const N="grafana-assistant-app/callback/v0-alpha";function U(e,t){return{namespace:e,functions:t}}function D(e){return{title:"callback",targets:[N],fn:()=>e.map((e=>({namespace:e.namespace,functions:e.functions})))}}const I=require("rxjs");function S(){return(0,h.getObservablePluginLinks)({extensionPointId:"grafana/extension-sidebar/v0-alpha"}).pipe((0,I.map)((e=>e.some((e=>"grafana-assistant-app"===e.pluginId&&"Grafana Assistant"===e.title)))))}const C=require("@grafana/data");class F extends C.BusEventWithPayload{}F.type="open-extension-sidebar";class P extends C.BusEventBase{}function A(e){!function(e,t,a){const n=new F({pluginId:"grafana-assistant-app",componentTitle:"Grafana Assistant",props:a});(0,h.getAppEvents)().publish(n)}(0,0,{initialPrompt:e.prompt,initialContext:e.context})}function V(){!function(){const e=new P;(0,h.getAppEvents)().publish(e)}()}function M(){const[e,t]=(0,b.useState)(!1);return(0,b.useEffect)((()=>{const e=S().subscribe((e=>t(e)));return()=>{e.unsubscribe()}}),[]),[e,e?A:void 0,e?V:void 0]}P.type="close-extension-sidebar",module.exports=a})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafana/assistant",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Type definitions and helper functions for Grafana Assistant",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,10 +9,9 @@
9
9
  ],
10
10
  "scripts": {
11
11
  "prebuild": "rm -rf dist",
12
- "build:dev": "webpack --config webpack.config.cjs --mode development && tsc --emitDeclarationOnly",
13
12
  "build": "webpack --config webpack.config.cjs --mode production && tsc --emitDeclarationOnly",
14
- "clean": "rm -rf dist",
15
- "prepublishOnly": "npm run clean && npm run build"
13
+ "dev": "webpack --config webpack.config.cjs --mode development",
14
+ "clean": "rm -rf dist"
16
15
  },
17
16
  "keywords": [
18
17
  "grafana",
@@ -25,7 +24,7 @@
25
24
  "dependencies": {},
26
25
  "devDependencies": {
27
26
  "react": "18.3.1",
28
- "rxjs": "7.8.1",
27
+ "rxjs": "7.8.2",
29
28
  "ts-loader": "^9.0.0",
30
29
  "typescript": "^5.0.0",
31
30
  "webpack": "^5.0.0",
@@ -37,9 +36,9 @@
37
36
  "peerDependencies": {
38
37
  "react": ">=18.0.0",
39
38
  "rxjs": ">=7.0.0",
40
- "@grafana/data": ">=12.0.0",
41
- "@grafana/runtime": ">=12.0.0",
39
+ "@grafana/data": ">=12.1.0",
40
+ "@grafana/runtime": ">=12.1.0",
42
41
  "@grafana/scenes": ">=5.41.0",
43
- "@grafana/ui": ">=12.0.0"
42
+ "@grafana/ui": ">=12.1.0"
44
43
  }
45
44
  }