@grafana/assistant 0.0.12 → 0.0.13
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 +227 -16
- package/dist/context/index.d.ts +1 -0
- package/dist/context/page.d.ts +3 -1
- package/dist/context/questions.d.ts +39 -0
- package/dist/context/types.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ openAssistant({
|
|
|
86
86
|
|
|
87
87
|
### Providing Page-Specific Context
|
|
88
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
|
|
89
|
+
You can register context items that are automatically included when the assistant is opened on pages matching specific URL patterns. The `providePageContext` function returns a setter function that allows you to update the context dynamically:
|
|
90
90
|
|
|
91
91
|
```typescript
|
|
92
92
|
import { providePageContext, createContext } from '@grafana/assistant';
|
|
@@ -116,16 +116,61 @@ setContext([
|
|
|
116
116
|
})
|
|
117
117
|
]);
|
|
118
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
119
|
// Clean up when no longer needed
|
|
126
120
|
setContext.unregister();
|
|
127
121
|
```
|
|
128
122
|
|
|
123
|
+
### Using Page Context in React Components
|
|
124
|
+
|
|
125
|
+
For React components, use the `useProvidePageContext` hook which automatically handles cleanup:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { useProvidePageContext, createContext } from '@grafana/assistant';
|
|
129
|
+
|
|
130
|
+
function DashboardComponent() {
|
|
131
|
+
const dashboardContext = createContext('structured', {
|
|
132
|
+
data: {
|
|
133
|
+
name: 'Dashboard Context',
|
|
134
|
+
pageType: 'dashboard'
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Automatically cleans up on unmount
|
|
139
|
+
const setContext = useProvidePageContext('/d/*', [dashboardContext]);
|
|
140
|
+
|
|
141
|
+
// Update context when needed
|
|
142
|
+
const handlePanelSelect = (panelId: string) => {
|
|
143
|
+
setContext([
|
|
144
|
+
dashboardContext,
|
|
145
|
+
createContext('structured', {
|
|
146
|
+
data: {
|
|
147
|
+
name: 'Panel Context',
|
|
148
|
+
selectedPanel: panelId
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
]);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
return <div>Dashboard content</div>;
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Accessing Current Page Context
|
|
159
|
+
|
|
160
|
+
Use the `usePageContext` hook to access all active context for the current page:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
import { usePageContext } from '@grafana/assistant';
|
|
164
|
+
|
|
165
|
+
function MyComponent() {
|
|
166
|
+
const pageContext = usePageContext();
|
|
167
|
+
|
|
168
|
+
console.log('Active context items:', pageContext);
|
|
169
|
+
|
|
170
|
+
return <div>Page has {pageContext.length} context items</div>;
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
129
174
|
### Creating Context Items
|
|
130
175
|
|
|
131
176
|
The `createContext` function allows you to create structured context items that provide the assistant with additional information about your Grafana resources.
|
|
@@ -182,6 +227,7 @@ const structuredContext = createContext('structured', {
|
|
|
182
227
|
|
|
183
228
|
// Create generic context
|
|
184
229
|
const genericContext = createContext('unknown', {
|
|
230
|
+
id: 'my-context',
|
|
185
231
|
text: 'Some additional context information'
|
|
186
232
|
});
|
|
187
233
|
```
|
|
@@ -221,7 +267,7 @@ export const getExtensionConfigs = () => [
|
|
|
221
267
|
|
|
222
268
|
### React Hooks
|
|
223
269
|
|
|
224
|
-
#### `useAssistant():
|
|
270
|
+
#### `useAssistant(): [boolean, ((props: OpenAssistantProps) => void) | undefined, (() => void) | undefined]`
|
|
225
271
|
|
|
226
272
|
A React hook that provides assistant availability status and control functions.
|
|
227
273
|
|
|
@@ -230,6 +276,22 @@ A React hook that provides assistant availability status and control functions.
|
|
|
230
276
|
- `openAssistant?: (props: OpenAssistantProps) => void` - Function to open the assistant (undefined if not available)
|
|
231
277
|
- `closeAssistant?: () => void` - Function to close the assistant (undefined if not available)
|
|
232
278
|
|
|
279
|
+
#### `usePageContext(): ChatContextItem[]`
|
|
280
|
+
|
|
281
|
+
A React hook that returns all active context items for the current page based on registered URL patterns.
|
|
282
|
+
|
|
283
|
+
**Returns:** Array of `ChatContextItem` objects that match the current page URL.
|
|
284
|
+
|
|
285
|
+
#### `useProvidePageContext(urlPattern: string | RegExp, initialContext?: ChatContextItem[]): (context: ChatContextItem[]) => void`
|
|
286
|
+
|
|
287
|
+
A React hook for providing page context that automatically cleans up on unmount. This is the recommended way to use page context in React components.
|
|
288
|
+
|
|
289
|
+
**Parameters:**
|
|
290
|
+
- `urlPattern` - URL pattern (string or RegExp) to match against page URLs
|
|
291
|
+
- `initialContext` - Initial array of ChatContextItem to provide when the pattern matches (defaults to empty array)
|
|
292
|
+
|
|
293
|
+
**Returns:** A setter function to update the context
|
|
294
|
+
|
|
233
295
|
### Availability Functions
|
|
234
296
|
|
|
235
297
|
#### `isAssistantAvailable(): Observable<boolean>`
|
|
@@ -274,7 +336,7 @@ Creates a context item that can be passed to the assistant to provide additional
|
|
|
274
336
|
|
|
275
337
|
#### `providePageContext(urlPattern: string | RegExp, initialContext: ChatContextItem[]): ((context: ChatContextItem[]) => void) & { unregister: () => void }`
|
|
276
338
|
|
|
277
|
-
Registers context items for specific pages based on URL patterns. Returns a setter function to update the context dynamically
|
|
339
|
+
Registers context items for specific pages based on URL patterns. Returns a setter function to update the context dynamically. The context will be automatically included when the assistant is opened on pages matching the pattern.
|
|
278
340
|
|
|
279
341
|
**Parameters:**
|
|
280
342
|
- `urlPattern` - URL pattern (string with wildcards or RegExp) to match against page URLs
|
|
@@ -300,7 +362,105 @@ setDashboardContext([...newContext]);
|
|
|
300
362
|
setDashboardContext.unregister();
|
|
301
363
|
```
|
|
302
364
|
|
|
365
|
+
### Questions System
|
|
366
|
+
|
|
367
|
+
The questions system allows external parties to provide sample prompts with optional context for specific pages. It reuses the existing page context infrastructure but presents a simpler interface focused on questions.
|
|
368
|
+
|
|
369
|
+
#### `provideQuestions(urlPattern: string | RegExp, initialQuestions: Question[]): ((questions: Question[]) => void) & { unregister: () => void }`
|
|
370
|
+
|
|
371
|
+
Registers questions for specific pages based on URL patterns. Returns a setter function to update the questions dynamically.
|
|
372
|
+
|
|
373
|
+
**Parameters:**
|
|
374
|
+
- `urlPattern` - URL pattern (string with wildcards or RegExp) to match against page URLs
|
|
375
|
+
- `initialQuestions` - Initial array of `Question` to provide when the pattern matches
|
|
376
|
+
|
|
377
|
+
**Returns:** A setter function to update the questions, with an `unregister` method attached for cleanup
|
|
378
|
+
|
|
379
|
+
**Examples:**
|
|
380
|
+
```typescript
|
|
381
|
+
// Register questions for dashboard pages
|
|
382
|
+
const setQuestions = provideQuestions("/d/*", [
|
|
383
|
+
{
|
|
384
|
+
prompt: "What metrics are available in this dashboard?",
|
|
385
|
+
context: [], // Optional context items created with `createContext`
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
prompt: "How can I optimize the queries in this dashboard?",
|
|
389
|
+
context: [
|
|
390
|
+
createContext("dashboard", {
|
|
391
|
+
dashboardUid: 'dashboard-uid',
|
|
392
|
+
dashboardTitle: 'System Overview',
|
|
393
|
+
folderUid: 'folder-uid',
|
|
394
|
+
folderTitle: 'Production'
|
|
395
|
+
}),
|
|
396
|
+
],
|
|
397
|
+
},
|
|
398
|
+
]);
|
|
399
|
+
|
|
400
|
+
// Update questions dynamically
|
|
401
|
+
setQuestions([
|
|
402
|
+
{
|
|
403
|
+
prompt: "What are the key insights from this dashboard?",
|
|
404
|
+
context: []
|
|
405
|
+
}
|
|
406
|
+
]);
|
|
407
|
+
|
|
408
|
+
// Cleanup when done
|
|
409
|
+
setQuestions.unregister();
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
#### `useProvideQuestions(urlPattern: string | RegExp, initialQuestions?: Question[]): (questions: Question[]) => void`
|
|
413
|
+
|
|
414
|
+
React hook for providing questions that automatically cleans up on unmount. This is the recommended way to use questions in React components.
|
|
415
|
+
|
|
416
|
+
**Parameters:**
|
|
417
|
+
- `urlPattern` - URL pattern (string or RegExp) to match against page URLs
|
|
418
|
+
- `initialQuestions` - Initial array of questions to provide when the pattern matches (defaults to empty array)
|
|
419
|
+
|
|
420
|
+
**Returns:** A setter function to update the questions
|
|
421
|
+
|
|
422
|
+
**Example:**
|
|
423
|
+
```typescript
|
|
424
|
+
function DashboardComponent() {
|
|
425
|
+
const setQuestions = useProvideQuestions('/d/*', [
|
|
426
|
+
{
|
|
427
|
+
prompt: "What does this dashboard show?",
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
prompt: "How can I improve this dashboard?",
|
|
431
|
+
}
|
|
432
|
+
]);
|
|
433
|
+
|
|
434
|
+
return <div>Dashboard</div>;
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
#### `useQuestions(): Question[]`
|
|
303
439
|
|
|
440
|
+
React hook to get all questions that match the current URL. This filters the page context to only return question-type items.
|
|
441
|
+
|
|
442
|
+
**Returns:** Array of questions from all matching registrations
|
|
443
|
+
|
|
444
|
+
**Example:**
|
|
445
|
+
```typescript
|
|
446
|
+
function AssistantComponent() {
|
|
447
|
+
const questions = useQuestions();
|
|
448
|
+
|
|
449
|
+
return (
|
|
450
|
+
<div>
|
|
451
|
+
<h3>Suggested Questions:</h3>
|
|
452
|
+
{questions.map((question, index) => (
|
|
453
|
+
<div key={index}>
|
|
454
|
+
<p>{question.prompt}</p>
|
|
455
|
+
{question.context && question.context.length > 0 && (
|
|
456
|
+
<p>Has additional context</p>
|
|
457
|
+
)}
|
|
458
|
+
</div>
|
|
459
|
+
))}
|
|
460
|
+
</div>
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
```
|
|
304
464
|
|
|
305
465
|
### Sidebar Types
|
|
306
466
|
|
|
@@ -310,7 +470,6 @@ setDashboardContext.unregister();
|
|
|
310
470
|
type OpenAssistantProps = {
|
|
311
471
|
prompt?: string;
|
|
312
472
|
context?: ChatContextItem[];
|
|
313
|
-
includePageContext?: boolean;
|
|
314
473
|
};
|
|
315
474
|
```
|
|
316
475
|
|
|
@@ -318,7 +477,6 @@ Configuration object for opening the assistant.
|
|
|
318
477
|
|
|
319
478
|
- `prompt` - Optional initial prompt to display
|
|
320
479
|
- `context` - Optional context items to provide
|
|
321
|
-
- `includePageContext` - Whether to automatically include page context for the current URL (defaults to true)
|
|
322
480
|
|
|
323
481
|
#### `ChatContextItem`
|
|
324
482
|
|
|
@@ -331,7 +489,44 @@ type ChatContextItem = {
|
|
|
331
489
|
|
|
332
490
|
A context item that provides structured information to the assistant.
|
|
333
491
|
|
|
492
|
+
### Page Context Types
|
|
493
|
+
|
|
494
|
+
#### `PageContextRegistration`
|
|
334
495
|
|
|
496
|
+
```typescript
|
|
497
|
+
interface PageContextRegistration {
|
|
498
|
+
id: string;
|
|
499
|
+
urlPattern: string | RegExp;
|
|
500
|
+
context: ChatContextItem[];
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
Represents a registered page context mapping.
|
|
505
|
+
|
|
506
|
+
### Questions Types
|
|
507
|
+
|
|
508
|
+
#### `Question`
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
interface Question {
|
|
512
|
+
prompt: string; // The sample prompt/question
|
|
513
|
+
context?: ChatContextItem[]; // Optional context items
|
|
514
|
+
}
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
Represents a question with an optional prompt and context.
|
|
518
|
+
|
|
519
|
+
#### `QuestionRegistration`
|
|
520
|
+
|
|
521
|
+
```typescript
|
|
522
|
+
interface QuestionRegistration {
|
|
523
|
+
id: string;
|
|
524
|
+
urlPattern: string | RegExp;
|
|
525
|
+
questions: Question[];
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
Represents a registered questions mapping.
|
|
335
530
|
|
|
336
531
|
### Context Types
|
|
337
532
|
|
|
@@ -400,10 +595,7 @@ interface CreateLabelValueContextParams {
|
|
|
400
595
|
|
|
401
596
|
```typescript
|
|
402
597
|
interface StructuredNodeDataParams {
|
|
403
|
-
data:
|
|
404
|
-
name: string;
|
|
405
|
-
[key: string]: any;
|
|
406
|
-
};
|
|
598
|
+
data: Record<string, any>;
|
|
407
599
|
title?: string;
|
|
408
600
|
icon?: IconName;
|
|
409
601
|
}
|
|
@@ -413,7 +605,8 @@ interface StructuredNodeDataParams {
|
|
|
413
605
|
|
|
414
606
|
```typescript
|
|
415
607
|
interface NodeDataParams {
|
|
416
|
-
|
|
608
|
+
id: string;
|
|
609
|
+
text?: string;
|
|
417
610
|
title?: string;
|
|
418
611
|
icon?: IconName;
|
|
419
612
|
}
|
|
@@ -483,6 +676,24 @@ const CALLBACK_EXTENSION_POINT = 'grafana-assistant-app/callback/v0-alpha';
|
|
|
483
676
|
|
|
484
677
|
The extension point ID for registering assistant functions.
|
|
485
678
|
|
|
679
|
+
### Additional Exported Types
|
|
680
|
+
|
|
681
|
+
The package also exports the following types for advanced use cases:
|
|
682
|
+
|
|
683
|
+
```typescript
|
|
684
|
+
// Data types for context items
|
|
685
|
+
export type DashboardNodeData;
|
|
686
|
+
export type DatasourceNodeData;
|
|
687
|
+
export type FolderNodeData;
|
|
688
|
+
export type LabelNameNodeData;
|
|
689
|
+
export type LabelValueNodeData;
|
|
690
|
+
export type StructuredNodeData;
|
|
691
|
+
export type TreeNode;
|
|
692
|
+
|
|
693
|
+
// Enums
|
|
694
|
+
export enum ItemDataType;
|
|
695
|
+
```
|
|
696
|
+
|
|
486
697
|
## License
|
|
487
698
|
|
|
488
699
|
Apache-2.0
|
package/dist/context/index.d.ts
CHANGED
package/dist/context/page.d.ts
CHANGED
|
@@ -26,4 +26,6 @@ export declare function providePageContext(urlPattern: string | RegExp, initialC
|
|
|
26
26
|
* @returns A setter function to update the context
|
|
27
27
|
*/
|
|
28
28
|
export declare function useProvidePageContext(urlPattern: string | RegExp, initialContext?: ChatContextItem[]): (context: ChatContextItem[]) => void;
|
|
29
|
-
export declare function usePageContext(
|
|
29
|
+
export declare function usePageContext(options?: {
|
|
30
|
+
allowQuestions: boolean;
|
|
31
|
+
}): ChatContextItem[];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ChatContextItem } from './types';
|
|
2
|
+
export interface Question {
|
|
3
|
+
prompt: string;
|
|
4
|
+
context?: ChatContextItem[];
|
|
5
|
+
}
|
|
6
|
+
export interface QuestionRegistration {
|
|
7
|
+
id: string;
|
|
8
|
+
urlPattern: string | RegExp;
|
|
9
|
+
questions: Question[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Registers questions for specific pages based on URL patterns.
|
|
13
|
+
* Returns a setter function to update the questions dynamically, similar to useState.
|
|
14
|
+
*
|
|
15
|
+
* If a registration with the same URL pattern already exists, it will be replaced.
|
|
16
|
+
*
|
|
17
|
+
* @param urlPattern - URL pattern (string or RegExp) to match against page URLs
|
|
18
|
+
* @param initialQuestions - Initial array of questions to provide when the pattern matches
|
|
19
|
+
* @returns A setter function to update the questions, with an unregister method attached
|
|
20
|
+
*/
|
|
21
|
+
export declare function provideQuestions(urlPattern: string | RegExp, initialQuestions: Question[]): ((questions: Question[]) => void) & {
|
|
22
|
+
unregister: () => void;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* React hook for providing questions that automatically cleans up on unmount.
|
|
26
|
+
* This is the recommended way to use questions in React components.
|
|
27
|
+
*
|
|
28
|
+
* @param urlPattern - URL pattern (string or RegExp) to match against page URLs
|
|
29
|
+
* @param initialQuestions - Initial array of questions to provide when the pattern matches
|
|
30
|
+
* @returns A setter function to update the questions
|
|
31
|
+
*/
|
|
32
|
+
export declare function useProvideQuestions(urlPattern: string | RegExp, initialQuestions?: Question[]): (questions: Question[]) => void;
|
|
33
|
+
/**
|
|
34
|
+
* React hook to get all questions that match the current URL.
|
|
35
|
+
* This filters the page context to only return question-type items.
|
|
36
|
+
*
|
|
37
|
+
* @returns Array of questions from all matching registrations
|
|
38
|
+
*/
|
|
39
|
+
export declare function useQuestions(): Question[];
|
package/dist/context/types.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createContext, ChatContextItem, DashboardNodeData, DatasourceNodeData, FolderNodeData, ItemDataType, LabelNameNodeData, LabelValueNodeData, StructuredNodeData, TreeNode, providePageContext, PageContextRegistration, usePageContext, } from './context/index';
|
|
1
|
+
export { createContext, ChatContextItem, DashboardNodeData, DatasourceNodeData, FolderNodeData, ItemDataType, LabelNameNodeData, LabelValueNodeData, StructuredNodeData, TreeNode, providePageContext, PageContextRegistration, usePageContext, provideQuestions, useProvideQuestions, useQuestions, Question, QuestionRegistration, } 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,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:()=>
|
|
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:()=>I,DashboardNodeData:()=>o,DatasourceNodeData:()=>d,FolderNodeData:()=>i,ItemDataType:()=>e,LabelNameNodeData:()=>l,LabelValueNodeData:()=>u,StructuredNodeData:()=>r,closeAssistant:()=>_,createContext:()=>f,getExposeAssistantFunctionsConfig:()=>C,isAssistantAvailable:()=>F,newFunctionNamespace:()=>A,openAssistant:()=>$,providePageContext:()=>y,provideQuestions:()=>N,useAssistant:()=>k,usePageContext:()=>L,useProvideQuestions:()=>U,useQuestions:()=>D}),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.text="",this.id=n(e.id)}formatForLLM(t){var a,n;return{type:e.Unknown,codeElementIds:t,data:{name:null!==(a=this.params.text)&&void 0!==a?a:"",text:null!==(n=this.params.text)&&void 0!==n?n:""}}}}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.text="",this.dashboardUid=e.dashboardUid,this.dashboardTitle=e.dashboardTitle,this.folderUid=e.folderUid,this.folderTitle=e.folderTitle,this.text=e.dashboardTitle}formatForLLM(t){return{type:e.Dashboard,codeElementIds:t,data:{name:this.dashboardTitle,dashboardUid:this.dashboardUid,dashboardTitle:this.dashboardTitle,folderUid:this.folderUid,folderTitle:this.folderTitle,text:this.text}}}}class i extends s{constructor(e){super({...e,id:e.folderUid}),this.text="",this.folderUid=e.folderUid,this.folderTitle=e.folderTitle,this.text=e.folderTitle}formatForLLM(t){return{type:e.DashboardFolder,codeElementIds:t,data:{name:this.folderTitle,folderUid:this.folderUid,folderTitle:this.folderTitle,text:this.text}}}}class d extends s{constructor(e){super({...e,id:e.datasourceUid}),this.text="",this.datasourceUid=e.datasourceUid,this.datasourceType=e.datasourceType,this.datasourceName=e.datasourceName,this.text=e.datasourceName}formatForLLM(t){return{type:e.Datasource,codeElementIds:t,data:{name:this.datasourceName,uid:this.datasourceUid,type:this.datasourceType,text:this.text}}}}class l extends s{constructor(e){super({...e,id:`${e.datasourceUid}-${e.labelName}`}),this.text="",this.datasourceUid=e.datasourceUid,this.datasourceType=e.datasourceType,this.labelName=e.labelName,this.text=e.labelName}formatForLLM(t){return{type:e.LabelName,codeElementIds:t,data:{name:this.labelName,datasourceUid:this.datasourceUid,datasourceType:this.datasourceType,labelName:this.labelName,text:this.text}}}}class u extends s{constructor(e){super({...e,id:`${e.datasourceUid}-${e.labelName}-${e.labelValue}`}),this.text="",this.datasourceUid=e.datasourceUid,this.datasourceType=e.datasourceType,this.labelName=e.labelName,this.labelValue=e.labelValue,this.text=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,text:this.text}}}}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 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 d(t);case"label_name":return new l(t);case"label_value":return new u(t);case"dashboard":return new o(t);case"dashboard_folder":return new i(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:c[e],navigable:!1,selectable:!0,data:f},occurrences:[]}}const h=require("@grafana/runtime"),m=require("react"),b=[],v="grafana-assistant:page-context-sync",x="grafana-assistant:page-context-update",g="grafana-assistant:page-context-remove",w="grafana-assistant:location-changed";let E=!1;function y(e,t){const a=b.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=b[a],n.context=[...t]):(n={id:`page-context-${Date.now()}-${Math.random().toString(36).slice(2,11)}`,urlPattern:e,context:[...t]},b.push(n)),window.dispatchEvent(new CustomEvent(x,{detail:n})),window.dispatchEvent(new CustomEvent(v,{detail:{registry:b}}));const s=e=>{const t=b.findIndex((e=>e.id===n.id));-1!==t&&(b[t].context=[...e],window.dispatchEvent(new CustomEvent(x,{detail:b[t]})))};return s.unregister=()=>{const e=b.findIndex((e=>e.id===n.id));-1!==e&&(b.splice(e,1),window.dispatchEvent(new CustomEvent(g,{detail:{id:n.id}})))},s}function L(e={allowQuestions:!1}){const[t,a]=(0,m.useState)([]),n=(0,h.useLocationService)(),s=(0,m.useRef)("");return(0,m.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}(n.getLocation().pathname,b);a(e)},t=()=>{e()},r=t=>{var a;const s=null===(a=t.detail)||void 0===a?void 0:a.pathname;s&&s===n.getLocation().pathname&&e()},o=n.getLocationObservable().subscribe((t=>{const a=t.pathname;a!==s.current&&(s.current=a,function(e){window.dispatchEvent(new CustomEvent(w,{detail:{pathname:e}}))}(a),e())}));return e(),window.addEventListener(v,t),window.addEventListener(x,t),window.addEventListener(g,t),window.addEventListener(w,r),()=>{o.unsubscribe(),window.removeEventListener(v,t),window.removeEventListener(x,t),window.removeEventListener(g,t),window.removeEventListener(w,r)}}),[n]),e.allowQuestions?t:t.filter((e=>{var t;return"question"!==(null===(t=e.node.data)||void 0===t?void 0:t.type)}))}function T(e,t){if(t instanceof RegExp)return t.test(e);if("string"==typeof t){const a=t.replace(/\*\*/g,"\0DOUBLE_STAR\0").replace(/\*/g,"[^/]*").replace(/\u0000DOUBLE_STAR\u0000/g,".*").replace(/\?/g,".");return new RegExp(`^${a}$`).test(e)}return!1}function N(e,t){const a=e=>e.map(((e,t)=>({node:{id:`question-${t}`,name:e.prompt,navigable:!1,selectable:!0,icon:"question-circle",data:{type:"question",prompt:e.prompt,context:e.context||[]}},occurrences:[]}))),n=y(e,a(t)),s=e=>{n(a(e))};return s.unregister=n.unregister,s}function U(e,t=[]){const a=e=>e.map(((e,t)=>({node:{id:`question-${t}`,name:e.prompt,navigable:!1,selectable:!0,icon:"question-circle",data:{type:"question",prompt:e.prompt,context:e.context||[]}},occurrences:[]}))),n=function(e,t=[]){const a=(0,m.useRef)(),n=(0,m.useRef)(t);return n.current=t,(0,m.useEffect)((()=>(a.current=y(e,n.current),()=>{var e;null===(e=a.current)||void 0===e||e.unregister()})),[e]),(0,m.useEffect)((()=>{a.current&&a.current(t)}),[t]),(0,m.useCallback)((e=>{var t;null===(t=a.current)||void 0===t||t.call(a,e)}),[])}(e,a(t));return e=>{n(a(e))}}function D(){const e=L({allowQuestions:!0});return S(e)}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(b.map((e=>e.id))),t=a.filter((t=>!e.has(t.id)));b.push(...t)}})),window.addEventListener(x,(e=>{const t=e.detail;if(t){const e=b.findIndex((e=>e.id===t.id));-1!==e?b[e]=t:b.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=b.findIndex((e=>e.id===a));-1!==e&&b.splice(e,1)}})),E=!0);const S=e=>e.filter((e=>{var t;return"question"===(null===(t=e.node.data)||void 0===t?void 0:t.type)})).map((e=>{var t,a;return{prompt:(null===(t=e.node.data)||void 0===t?void 0:t.prompt)||e.node.name,context:(null===(a=e.node.data)||void 0===a?void 0:a.context)||[]}})),I="grafana-assistant-app/callback/v0-alpha";function A(e,t){return{namespace:e,functions:t}}function C(e){return{title:"callback",targets:[I],fn:()=>e.map((e=>({namespace:e.namespace,functions:e.functions})))}}const P=require("rxjs");function F(){return(0,h.getObservablePluginLinks)({extensionPointId:"grafana/extension-sidebar/v0-alpha"}).pipe((0,P.map)((e=>e.some((e=>"grafana-assistant-app"===e.pluginId&&"Grafana Assistant"===e.title)))))}const V=require("@grafana/data");class q extends V.BusEventWithPayload{}q.type="open-extension-sidebar";class O extends V.BusEventBase{}function $(e){!function(e,t,a){const n=new q({pluginId:"grafana-assistant-app",componentTitle:"Grafana Assistant",props:a});(0,h.getAppEvents)().publish(n)}(0,0,{initialPrompt:e.prompt,initialContext:e.context})}function _(){!function(){const e=new O;(0,h.getAppEvents)().publish(e)}()}function k(){const[e,t]=(0,m.useState)(!1);return(0,m.useEffect)((()=>{const e=F().subscribe((e=>t(e)));return()=>{e.unsubscribe()}}),[]),[e,e?$:void 0,e?_:void 0]}O.type="close-extension-sidebar",module.exports=a})();
|