@grafana/assistant
v0.1.7
Published
Type definitions and helper functions for Grafana Assistant
Maintainers
Readme
@grafana/assistant
Type definitions and utilities for integrating with the Grafana Assistant.
Installation
npm install @grafana/assistantUsage
Checking Assistant Availability
import { isAssistantAvailable } from '@grafana/assistant';
// Check if the assistant is available
isAssistantAvailable().subscribe((available) => {
if (available) {
console.log('Assistant is available');
}
});Using the Assistant Hook (React)
import { useAssistant } from '@grafana/assistant';
function MyComponent() {
const { isAvailable, openAssistant, closeAssistant } = useAssistant();
if (!isAvailable || !openAssistant) {
return <div>Assistant not available</div>;
}
return (
<button onClick={() => openAssistant({
origin: 'grafana/panel-data-analyzer',
prompt: 'Help me analyze data' })}>
Open Assistant
</button>
);
}Opening the Assistant Sidebar
import { openAssistant, closeAssistant } from '@grafana/assistant';
// Open the assistant with an initial prompt
openAssistant({ origin: 'grafana/some-feature', prompt: 'Show me CPU usage over the last hour' });
// Open the assistant with initial prompt and autoSend set to false
openAssistant({ origin: 'grafana-datasources/prometheus/some-feature', prompt: 'Help me analyze data', autoSend: false })
// Open the assistant without an initial prompt
openAssistant({
origin: 'grafana-slo-app/some-page',
});
// Close the assistant
closeAssistant();Using Context with the Assistant
import { openAssistant, createAssistantContextItem } from '@grafana/assistant';
// Create context items to provide additional information to the assistant
const datasourceContext = createAssistantContextItem('datasource', {
datasourceUid: 'prometheus-uid',
});
const dashboardContext = createAssistantContextItem('dashboard', {
dashboardUid: 'dashboard-uid',
dashboardTitle: 'System Overview',
folderUid: 'folder-uid',
folderTitle: 'Production'
});
// Open the assistant with initial prompt and context
openAssistant({
origin: 'grafana/dashboard-page',
prompt: 'Analyze the CPU metrics from this dashboard',
context: [datasourceContext, dashboardContext]
});
// Create hidden context for system instructions (won't show in UI pills)
const systemInstructions = createAssistantContextItem('structured', {
hidden: true,
title: 'System Instructions',
data: {
instructions: 'When analyzing metrics, always consider seasonal patterns and anomalies',
preferences: 'Use clear, technical language and provide actionable insights'
}
});
// Include hidden context with visible context
openAssistant({
prompt: 'What are the trends in this data?',
context: [datasourceContext, systemInstructions]
});Providing Page-Specific Context
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:
import { providePageContext, createAssistantContextItem } from '@grafana/assistant';
// Create initial context for dashboard pages
const dashboardContext = createAssistantContextItem('structured', {
data: {
name: 'Dashboard Context',
pageType: 'dashboard',
capabilities: ['view', 'edit', 'share'],
help: 'Use the assistant to analyze dashboard data, create queries, or troubleshoot issues.'
}
});
// Register context for all dashboard pages and get a setter function
const setContext = providePageContext('/d/*', [dashboardContext]);
// Later, dynamically update the context based on user interactions or data changes
setContext([
dashboardContext,
createAssistantContextItem('structured', {
data: {
name: 'Panel Context',
selectedPanel: 'cpu-usage-panel',
panelType: 'graph'
}
})
]);
// Clean up when no longer needed
setContext.unregister();
// Example: Provide hidden system instructions for explore pages
providePageContext('/explore', [
createAssistantContextItem('structured', {
hidden: true,
title: 'Additional instructions',
data: {
'System Instructions': 'When working with explore queries, always validate the time range and check for data availability. Suggest using recording rules for expensive queries.',
},
}),
]);Using Page Context in React Components
For React components, use the useProvidePageContext hook which automatically handles cleanup:
import { useProvidePageContext, createAssistantContextItem } from '@grafana/assistant';
function DashboardComponent() {
const dashboardContext = createAssistantContextItem('structured', {
data: {
name: 'Dashboard Context',
pageType: 'dashboard'
}
});
// Automatically cleans up on unmount
const setContext = useProvidePageContext('/d/*', [dashboardContext]);
// Update context when needed
const handlePanelSelect = (panelId: string) => {
setContext([
dashboardContext,
createAssistantContextItem('structured', {
data: {
name: 'Panel Context',
selectedPanel: panelId
}
})
]);
};
return <div>Dashboard content</div>;
}Accessing Current Page Context
Use the usePageContext hook to access all active context for the current page:
import { usePageContext } from '@grafana/assistant';
function MyComponent() {
const pageContext = usePageContext();
console.log('Active context items:', pageContext);
return <div>Page has {pageContext.length} context items</div>;
}Creating Context Items
The createAssistantContextItem function allows you to create structured context items that provide the assistant with additional information about your Grafana resources.
import { createAssistantContextItem } from '@grafana/assistant';
// Create a datasource context
const datasourceContext = createAssistantContextItem('datasource', {
datasourceUid: 'prom-123',
title: 'Main Datasource', // Optional custom title
icon: 'database' // Optional custom icon
});
// Create a dashboard context
const dashboardContext = createAssistantContextItem('dashboard', {
dashboardUid: 'dash-456',
dashboardTitle: 'Application Overview',
folderUid: 'folder-789',
folderTitle: 'Production Dashboards'
});
// Create a label context
const labelContext = createAssistantContextItem('label_name', {
datasourceUid: 'prom-123',
datasourceType: 'prometheus',
labelName: 'service'
});
// Create a label value context
const labelValueContext = createAssistantContextItem('label_value', {
datasourceUid: 'prom-123',
datasourceType: 'prometheus',
labelName: 'service',
labelValue: 'api-server'
});
// Create a folder context
const folderContext = createAssistantContextItem('dashboard_folder', {
folderUid: 'folder-789',
folderTitle: 'Production Dashboards'
});
// Create structured data context
const structuredContext = createAssistantContextItem('structured', {
data: {
name: 'Custom Data',
metrics: ['cpu_usage', 'memory_usage'],
threshold: 80
}
});
// Create generic context
const genericContext = createAssistantContextItem('unknown', {
id: 'my-context',
text: 'Some additional context information'
});
// Create component context for custom React components
const componentContext = createAssistantContextItem('component', {
components: {
MyCustomComponent: MyCustomComponentImplementation,
AnotherComponent: AnotherComponentImplementation,
},
prompt: `
- When mentioning specific entities, use the your_app_MyCustomComponent with the syntax: <your_app_MyCustomComponent prop1={'value1'} prop2={'value2'} />
- Custom components must never be wrapped in code blocks (backticks \` or \`\`\`).
- Always provide all required props when using custom components.
`,
namespace: 'your_app', // Optional: Namespace for your components (defaults to 'components')
});
// Create hidden context (useful for system instructions)
const hiddenInstructions = createAssistantContextItem('structured', {
hidden: true, // Won't be shown in UI pills but will be sent to the assistant
title: 'Page-specific instructions',
data: {
instructions: 'Always provide step-by-step explanations',
context: 'This is a complex system with multiple dependencies'
}
});Registering Custom Components for Assistant Usage
The component context type allows you to register custom React components that the assistant can use in its responses. This is particularly useful for rendering domain-specific UI elements that enhance the user experience.
⚠️ Important: Components must be approved by #grafana-assistant before usage. Please reach out to the Grafana Assistant team for review and approval of your custom components before implementing them in production.
Method 1: Using provideComponents (Recommended)
import { provideComponents } from '@grafana/assistant';
import MyEntityMention from 'components/MyEntityMentionComponent';
import MyCustomChart from 'components/MyCustomChartComponent';
/**
* Configure the assistant context for your app plugin.
* This sets up custom components that will be available to the Grafana Assistant
* when users are on any page matching the provided pattern.
*/
export function configureAssistantContext() {
provideComponents(
`
- When mentioning an entity in text, always use the your_app_MyEntityMention component: <your_app_MyEntityMention name={'entity name here'} type={'entity type here'} />
- For displaying charts, use the your_app_MyCustomChart component: <your_app_MyCustomChart data={chartData} title={'Chart Title'} />
- Custom components must never be wrapped in code blocks (backticks \` or \`\`\`).
`,
'your_app', // namespace
{
MyEntityMention,
MyCustomChart,
},
/.*/ // matches all pages
);
}Method 2: Using createAssistantContextItem with providePageContext
import { createAssistantContextItem, providePageContext } from '@grafana/assistant';
import MyEntityMention from 'components/MyEntityMentionComponent';
import MyCustomChart from 'components/MyCustomChartComponent';
export function configureAssistantContext() {
providePageContext(/.*/, [
createAssistantContextItem('component', {
components: {
MyEntityMention,
MyCustomChart,
},
prompt: `
- When mentioning an entity in text, always use the your_app_MyEntityMention component: <your_app_MyEntityMention name={'entity name here'} type={'entity type here'} />
- For displaying charts, use the your_app_MyCustomChart component: <your_app_MyCustomChart data={chartData} title={'Chart Title'} />
- Custom components must never be wrapped in code blocks (backticks \` or \`\`\`).
`,
namespace: 'your_app', // Optional: defaults to 'components' if not provided
}),
]);
}Key Points for Component Context:
- Approval Required: ⚠️ Components must be approved by #grafana-assistant before usage
- Components: A record of component names to their React component implementations
- Prompt: Instructions for the assistant on how and when to use these components
- Namespace: A unique identifier for your app's components (e.g., 'your_app', 'datasource'). Optional - defaults to 'components' if not provided
- Component Usage: Components are referenced in assistant responses as
<namespace_ComponentName prop={'value'} />(note the underscore format) - No Code Blocks: Custom components should never be wrapped in markdown code blocks
Example Component Implementation:
interface MyEntityMentionProps {
name: string;
type: string;
env?: string;
site?: string;
namespace?: string;
properties?: string;
}
const MyEntityMention: React.FC<MyEntityMentionProps> = ({ name, type, env, site, namespace, properties }) => {
return (
<span
className="entity-mention"
data-entity-type={type}
title={`${type}: ${name}`}
>
{name}
</span>
);
};
export default MyEntityMention;Using Hidden Context for System Instructions
The hidden parameter allows you to provide context to the assistant without showing it in the UI pills. This is particularly useful for:
- System instructions: Provide behavioral guidelines specific to certain pages
- Metadata: Include technical details that might confuse users if shown
- Contextual rules: Add page-specific rules without cluttering the interface
Example use cases:
// Provide exploration-specific guidelines
providePageContext('/explore', [
createAssistantContextItem('structured', {
hidden: true,
title: 'Explore Page Guidelines',
data: {
instructions: [
'Always validate time ranges before running queries',
'Suggest using recording rules for expensive queries',
'Warn about queries that might impact performance'
],
queryLimits: {
maxTimeRange: '24h',
suggestedSampleInterval: '1m'
}
}
})
]);
// Add dashboard-specific context
providePageContext('/d/*', [
createAssistantContextItem('structured', {
hidden: true,
title: 'Dashboard Instructions',
data: {
bestPractices: 'Encourage users to use template variables for flexibility',
performance: 'Suggest panel caching for slow queries'
}
})
]);Exposing Functions to the Assistant
import {
getExposeAssistantFunctionsConfig,
newFunctionNamespace,
FunctionImplementation,
FunctionNamespace,
NamedFunctions
} from '@grafana/assistant';
// Define your functions
const myFunctions: NamedFunctions = {
getMetrics: (datasource: string) => {
return ['cpu_usage', 'memory_usage', 'disk_io'];
},
calculateAverage: (values: number[]) => {
return values.reduce((a, b) => a + b, 0) / values.length;
}
};
// Create a namespace for your functions
const namespace = newFunctionNamespace('myPlugin', myFunctions);
// Export the configuration for your plugin
export const getExtensionConfigs = () => [
getExposeAssistantFunctionsConfig([namespace])
];Using the OpenAssistantButton Component
The OpenAssistantButton is a pre-built Button component that provides an easy way to add assistant functionality to your UI with a single button click. It automatically checks availability and hides itself if the Assistant is not available.
import { OpenAssistantButton, createAssistantContextItem } from '@grafana/assistant';
function MyDashboard() {
const dashboardContext = createAssistantContextItem('dashboard', {
dashboardUid: 'dashboard-123',
dashboardTitle: 'CPU Metrics Dashboard'
});
return (
<div>
<h1>Dashboard</h1>
{/* Basic usage */}
<OpenAssistantButton
prompt="Help me analyze the CPU usage trends in this dashboard"
context={[dashboardContext]}
origin="grafana/dashboard-menu"
/>
{/* Icon-only button */}
<OpenAssistantButton
prompt="Show me optimization suggestions"
iconOnlyButton={true}
name="Get AI suggestions"
size="md"
origin="grafana-datasources/loki/query-editor"
/>
{/* Button without auto-send */}
<OpenAssistantButton
prompt="What patterns do you see in the data?"
autoSend={false}
name="Ask Assistant"
size="lg"
origin="grafana/panel-viewer"
/>
</div>
);
}API Reference
React Hooks
useAssistant(): AssistantHook
A React hook that provides assistant availability status and control functions.
Returns: An object with the following properties:
isAvailable: boolean- Whether the Assistant is availableopenAssistant?: (props: OpenAssistantProps) => void- Function to open the assistant (undefined if not available)closeAssistant?: () => void- Function to close the assistant (undefined if not available)toggleAssistant?: (props: OpenAssistantProps) => void- Function to toggle the assistant (undefined if not available)
useTerms(): { accepted: boolean; loading: boolean; error: string | null; acceptTerms: () => Promise<void> }
A React hook to check terms and conditions acceptance status. Automatically fetches terms data on mount and provides loading/error states.
Returns: An object with the following properties:
accepted: boolean- Whether terms are accepted and up-to-dateloading: boolean- Whether the check is in progresserror: string | null- Error message if the check failed, null otherwiseacceptTerms: () => Promise<void>- Function to accept the current terms and conditions
usePageContext(): ChatContextItem[]
A React hook that returns all active context items for the current page based on registered URL patterns.
Returns: Array of ChatContextItem objects that match the current page URL.
useProvidePageContext(urlPattern: string | RegExp, initialContext?: ChatContextItem[]): (context: ChatContextItem[]) => void
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.
Parameters:
urlPattern- URL pattern (string or RegExp) to match against page URLsinitialContext- Initial array of ChatContextItem to provide when the pattern matches (defaults to empty array)
Returns: A setter function to update the context
usePageComponents(): Record<string, ComponentImplementation>
A React hook that provides all components available for the current page. This hook automatically updates when the URL changes or when component registrations change.
Returns: Object containing all components available for the current page, keyed by namespace_componentName format.
Example:
import { usePageComponents } from '@grafana/assistant';
function MyAssistantComponent() {
const components = usePageComponents();
// Access components registered with namespace 'myapp' and component name 'EntityMention'
const EntityMentionComponent = components['myapp_EntityMention'];
return (
<div>
Available components: {Object.keys(components).join(', ')}
</div>
);
}React Components
<OpenAssistantButton />
A pre-built React component that renders a button to open the Grafana Assistant with configurable prompt and context.
Parameters:
prompt: string- Required The initial prompt to display in the assistantorigin: string- Required Origin of the request that opened the assistant. Should be structured using forward slashes with the first part as a namespace. Examples: 'grafana-datasources/prometheus/query-builder', 'grafana-slo-app/slo-editor-overview'context?: ChatContextItem[]- Optional context items created withcreateAssistantContextItemautoSend?: boolean- Whether to automatically send the initial prompt (defaults totrue)title?: string- Text to display on the button (defaults to'Analyze with Assistant')size?: 'xs' | 'sm' | 'md' | 'lg'- Button size (defaults to'sm')iconOnlyButton?: boolean- Iftrue, renders as an icon-only button with tooltip (defaults tofalse)
<AITextInput />
An AI-powered text input component that uses the inline assistant to generate content. Features a gradient border animation while generating and an integrated send button. Perfect for generating short-form content like titles, labels, or names.
Parameters:
value: string- Required The current value of the input (controlled component)onChange: (value: string) => void- Required Called when the input value changesorigin: string- Required Origin for analytics tracking (e.g., 'grafana/panel-editor/title')placeholder?: string- Placeholder text (defaults to 'Ask AI to generate...')systemPrompt?: string- Optional system prompt to guide the assistant's behavioronComplete?: (text: string) => void- Callback when generation completes successfullyonError?: (error: Error) => void- Callback if an error occurs during generationonDelta?: (delta: string) => void- Callback for streaming tokens as they are received during generationdisabled?: boolean- Whether the input is disabledclassName?: string- Additional CSS class namedata-testid?: string- Test ID for testing
Example:
import { AITextInput } from '@grafana/assistant';
import { useState } from 'react';
function PanelEditor() {
const [title, setTitle] = useState('');
return (
<AITextInput
value={title}
onChange={setTitle}
origin="grafana/panel-editor/title"
systemPrompt="Generate a concise, descriptive panel title. Return only the title text."
placeholder="Ask AI to generate a title..."
onComplete={(text) => {
setTitle(text); // Update state to display the generated text
console.log('Generated:', text);
}}
/>
);
}<AITextArea />
An AI-powered textarea component that uses the inline assistant to generate longer content. Features a gradient border animation while generating and an integrated send button. Use Cmd/Ctrl+Enter to submit. Ideal for descriptions, documentation, or multi-line content generation.
Parameters:
value: string- Required The current value of the textarea (controlled component)onChange: (value: string) => void- Required Called when the textarea value changesorigin: string- Required Origin for analytics tracking (e.g., 'grafana/panel-editor/description')placeholder?: string- Placeholder text (defaults to 'Ask AI to generate... (Cmd/Ctrl+Enter to send)')systemPrompt?: string- Optional system prompt to guide the assistant's behavioronComplete?: (text: string) => void- Callback when generation completes successfullyonError?: (error: Error) => void- Callback if an error occurs during generationonDelta?: (delta: string) => void- Callback for streaming tokens as they are received during generationdisabled?: boolean- Whether the textarea is disabledrows?: number- Number of rows for the textarea (defaults to 4)className?: string- Additional CSS class namedata-testid?: string- Test ID for testing
Example:
import { AITextArea } from '@grafana/assistant';
import { useState } from 'react';
function DashboardEditor() {
const [description, setDescription] = useState('');
return (
<AITextArea
value={description}
onChange={setDescription}
origin="grafana/dashboard-editor/description"
systemPrompt="Generate a clear dashboard description in 2-3 sentences."
placeholder="Ask AI to generate a description... (Cmd/Ctrl+Enter to send)"
rows={6}
onComplete={(text) => {
setDescription(text); // Update state to display the generated text
console.log('Generated:', text);
}}
/>
);
}Using the Inline Assistant
The useInlineAssistant hook generates content inline without opening the sidebar — perfect for filling form fields with AI-generated text.
import { useInlineAssistant } from '@grafana/assistant';
import { useState } from 'react';
export function PanelEditor() {
const [title, setTitle] = useState('');
const titleGen = useInlineAssistant();
return (
<div>
<Input
value={titleGen.isGenerating ? titleGen.content : title}
onChange={(e) => setTitle(e.target.value)}
/>
<Button
onClick={() => {
titleGen.generate({
prompt: 'Generate a panel title for CPU metrics',
origin: 'my-plugin/panel-editor',
onComplete: (text) => setTitle(text),
onError: (err) => console.error(err)
});
}}
disabled={titleGen.isGenerating}
>
{titleGen.isGenerating ? 'Generating...' : 'Generate'}
</Button>
</div>
);
}Key Features:
isGenerating- Boolean indicating generation is in progresscontent- Current streaming content (updates in real-time)generate(options)- Start a new generation- Each instance is independent—use multiple for concurrent fields
Using Tools with Inline Assistant
Tools extend the assistant's capabilities with custom actions. Tools can return both text and structured data (artifacts). To access artifact data, include an onToolComplete callback in your tool implementation.
import { createTool } from '@grafana/assistant';
import { z } from 'zod';
import type { ToolInvokeOptions, ToolOutput } from '@grafana/assistant';
// Define artifact type
interface WeatherData {
city: string;
temperature: { celsius: number; fahrenheit: number };
conditions: string;
humidity: number;
}
// Create tool schema
const weatherSchema = z.object({
city: z.string().describe('The city name to get weather for'),
});
// Create tool that accepts onToolComplete callback
export const createWeatherTool = (onToolComplete: (data: WeatherData) => void) => {
return createTool(
async (input: z.infer<typeof weatherSchema>): Promise<ToolOutput> => {
const { city } = input;
// Fetch weather data (simplified example)
const weatherData: WeatherData = {
city,
temperature: { celsius: 22, fahrenheit: 72 },
conditions: 'Sunny',
humidity: 65,
};
// Call the callback to pass artifact data
onToolComplete(weatherData);
// Return tuple: [text response, artifact]
return [
`Current weather in ${city}: ${weatherData.temperature.celsius}°C, ${weatherData.conditions}`,
weatherData,
];
},
{
name: 'get_weather',
description: 'Fetches weather information and returns structured data.',
inputSchema: z.toJSONSchema(weatherSchema),
validate: (input) => weatherSchema.parse(input),
responseFormat: 'content_and_artifact',
}
);
};
// Use the tool with inline assistant
export function WeatherComponent() {
const [result, setResult] = useState('');
const [weatherData, setWeatherData] = useState<WeatherData | null>(null);
const gen = useInlineAssistant();
const handleGetWeather = () => {
gen.generate({
prompt: 'What is the weather in San Francisco?',
origin: 'my-plugin/weather',
tools: [createWeatherTool((data) => setWeatherData(data))], // Pass callback
onComplete: (text) => setResult(text),
onError: (err) => console.error(err),
});
};
return (
<div>
<Button onClick={handleGetWeather} disabled={gen.isGenerating}>
Get Weather
</Button>
{result && <div>{result}</div>}
{weatherData && <pre>{JSON.stringify(weatherData, null, 2)}</pre>}
</div>
);
}Availability Functions
isAssistantAvailable(): Observable<boolean>
Checks if the assistant plugin is available.
Returns: An RxJS Observable that emits true if the assistant is available, false otherwise.
Terms and Conditions Functions
checkTerms(): Promise<boolean>
Checks whether terms and conditions are accepted and up-to-date. This function verifies that:
- Terms have been accepted
- The accepted version matches or exceeds the current version
Returns: A promise that resolves to true if terms are accepted and up-to-date, false otherwise.
Throws: Error if the API call fails.
Example:
import { checkTerms } from '@grafana/assistant';
try {
const accepted = await checkTerms();
if (!accepted) {
// Show terms acceptance UI
}
} catch (error) {
// Handle error
console.error('Failed to check terms:', error);
}acceptTerms(): Promise<void>
Accepts terms and conditions for the current tenant. This function sends a PUT request to mark the current terms version as accepted.
Returns: A promise that resolves when terms are successfully accepted.
Throws: Error if the API call fails.
Example:
import { acceptTerms } from '@grafana/assistant';
try {
await acceptTerms();
console.log('Terms accepted successfully');
} catch (error) {
// Handle error
console.error('Failed to accept terms:', error);
}Example with useTerms hook:
import { useTerms } from '@grafana/assistant';
function TermsComponent() {
const { accepted, loading, error, acceptTerms } = useTerms();
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!accepted) {
return (
<div>
<p>Please accept the terms and conditions</p>
<button onClick={() => acceptTerms()}>Accept Terms</button>
</div>
);
}
return <div>Terms accepted</div>;
}Sidebar Functions
openAssistant(props: OpenAssistantProps): void
Opens the Grafana Assistant sidebar.
Parameters:
props: OpenAssistantProps- Configuration objectorigin: string- Origin of the request that opened the assistant. Should be structured using forward slashes with the first part as a namespace. Examples: 'grafana-datasources/prometheus/query-builder', 'grafana-slo-app/slo-editor-overview'prompt?: string- Optional initial prompt to display in the assistantcontext?: ChatContextItem[]- Optional context items to provide additional information to the assistantautoSend?: boolean- Optional flag to automatically send the initial prompt
closeAssistant(): void
Closes the Grafana Assistant sidebar.
Context Functions
createAssistantContextItem<T>(type: T, params: ContextTypeParams<T>): ChatContextItem
Creates a context item that can be passed to the assistant to provide additional information.
Parameters:
type- The type of context to create. Supported types:'datasource'- Datasource context'dashboard'- Dashboard context'dashboard_folder'- Folder context'label_name'- Label name context'label_value'- Label value context'structured'- Custom structured data context'component'- Custom React components context'unknown'- Generic text context
params- Parameters specific to the context type (see Context Types section). All context types support:hidden?: boolean- If true, the context item will not be shown in the UI pills but will still be sent to the assistant. This is useful for providing system instructions, behavioral guidelines, or other metadata that shouldn't clutter the user interface.
Returns: A ChatContextItem that can be passed to openAssistant
providePageContext(urlPattern: string | RegExp, initialContext: ChatContextItem[]): ((context: ChatContextItem[]) => void) & { unregister: () => void }
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.
Parameters:
urlPattern- URL pattern (string with wildcards or RegExp) to match against page URLs- String patterns support
*(match any characters) and**(match any path segments) - RegExp patterns provide full regex matching capabilities
- String patterns support
initialContext- Initial array ofChatContextItemto provide when the pattern matches
Returns: A setter function to update the context, with an unregister method attached for cleanup
Examples:
// String patterns - returns setter function
const setDashboardContext = providePageContext('/d/*', initialContext); // Match any dashboard
const setExploreContext = providePageContext('/explore**', initialContext); // Match explore and subpaths
// RegExp patterns
const setSpecificContext = providePageContext(/^\/d\/[a-zA-Z0-9]+$/, initialContext); // Match specific dashboard format
// Update context dynamically
setDashboardContext([...newContext]);
// Cleanup when done
setDashboardContext.unregister();provideComponents(prompt: string, namespace: string, components: Record<string, ComponentImplementation>, urlPattern?: string | RegExp): ((context: ChatContextItem[]) => void) & { unregister: () => void }
A simplified function for providing components to the assistant. This is a convenience wrapper around providePageContext specifically for registering components.
Parameters:
prompt- Instructions for the assistant on how and when to use these componentsnamespace- A unique identifier for your app's components (e.g., 'myapp', 'datasource')components- A record of component names to their React component implementationsurlPattern- Optional URL pattern to match against page URLs (defaults to/.*/- matches all pages)
Returns: A setter function to update the context, with an unregister method attached for cleanup
Example:
import { provideComponents } from '@grafana/assistant';
import MyEntityMention from './components/MyEntityMention';
import MyCustomChart from './components/MyCustomChart';
// Register components for all pages
const setComponents = provideComponents(
`
- When mentioning entities, use the myapp_MyEntityMention component: <myapp_MyEntityMention name={'entity-name'} type={'entity-type'} />
- For charts, use the myapp_MyCustomChart component: <myapp_MyCustomChart data={chartData} title={'Chart Title'} />
- Custom components must never be wrapped in code blocks.
`,
'myapp',
{
MyEntityMention,
MyCustomChart,
}
);
// Register components only for dashboard pages
const setDashboardComponents = provideComponents(
'Use components to enhance dashboard analysis.',
'dashboard',
{ MyEntityMention },
'/d/*'
);
// Cleanup when done
setComponents.unregister();Questions System
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.
provideQuestions(urlPattern: string | RegExp, initialQuestions: Question[]): ((questions: Question[]) => void) & { unregister: () => void }
Registers questions for specific pages based on URL patterns. Returns a setter function to update the questions dynamically.
Parameters:
urlPattern- URL pattern (string with wildcards or RegExp) to match against page URLsinitialQuestions- Initial array ofQuestionto provide when the pattern matches
Returns: A setter function to update the questions, with an unregister method attached for cleanup
Examples:
// Register questions for dashboard pages
const setQuestions = provideQuestions("/d/*", [
{
prompt: "What metrics are available in this dashboard?",
context: [], // Optional context items created with `createAssistantContextItem`
},
{
prompt: "How can I optimize the queries in this dashboard?",
context: [
createAssistantContextItem("dashboard", {
dashboardUid: 'dashboard-uid',
dashboardTitle: 'System Overview',
folderUid: 'folder-uid',
folderTitle: 'Production'
}),
],
},
]);
// Update questions dynamically
setQuestions([
{
prompt: "What are the key insights from this dashboard?",
context: []
}
]);
// Cleanup when done
setQuestions.unregister();useProvideQuestions(urlPattern: string | RegExp, initialQuestions?: Question[]): (questions: Question[]) => void
React hook for providing questions that automatically cleans up on unmount. This is the recommended way to use questions in React components.
Parameters:
urlPattern- URL pattern (string or RegExp) to match against page URLsinitialQuestions- Initial array of questions to provide when the pattern matches (defaults to empty array)
Returns: A setter function to update the questions
Example:
function DashboardComponent() {
const setQuestions = useProvideQuestions('/d/*', [
{
prompt: "What does this dashboard show?",
},
{
prompt: "How can I improve this dashboard?",
}
]);
return <div>Dashboard</div>;
}useQuestions(): Question[]
React hook to get all questions that match the current URL. This filters the page context to only return question-type items.
Returns: Array of questions from all matching registrations
Example:
function AssistantComponent() {
const questions = useQuestions();
return (
<div>
<h3>Suggested Questions:</h3>
{questions.map((question, index) => (
<div key={index}>
<p>{question.prompt}</p>
{question.context && question.context.length > 0 && (
<p>Has additional context</p>
)}
</div>
))}
</div>
);
}Sidebar Types
OpenAssistantProps
type OpenAssistantProps = {
prompt?: string;
context?: ChatContextItem[];
autoSend?: boolean;
};Configuration object for opening the assistant.
prompt- Optional initial prompt to displaycontext- Optional context items to provideautoSend- Optional flag to automatically send the initial prompt
ChatContextItem
type ChatContextItem = {
node: TreeNode;
occurrences: string[];
};A context item that provides structured information to the assistant.
Page Context Types
PageContextRegistration
interface PageContextRegistration {
id: string;
urlPattern: string | RegExp;
context: ChatContextItem[];
}Represents a registered page context mapping.
Questions Types
Question
interface Question {
prompt: string; // The sample prompt/question
context?: ChatContextItem[]; // Optional context items
}Represents a question with an optional prompt and context.
QuestionRegistration
interface QuestionRegistration {
id: string;
urlPattern: string | RegExp;
questions: Question[];
}Represents a registered questions mapping.
Context Types
Datasource Context Parameters
interface CreateDatasourceContextParams {
datasourceUid: string;
title?: string;
icon?: IconName;
hidden?: boolean; // If true, the context item will not be shown in the context pills
}Dashboard Context Parameters
interface CreateDashboardContextParams {
dashboardUid: string;
dashboardTitle: string;
folderUid?: string;
folderTitle?: string;
title?: string;
icon?: IconName;
hidden?: boolean; // If true, the context item will not be shown in the context pills
}Folder Context Parameters
interface CreateFolderContextParams {
folderUid: string;
folderTitle: string;
title?: string;
icon?: IconName;
hidden?: boolean; // If true, the context item will not be shown in the context pills
}Label Name Context Parameters
interface CreateLabelNameContextParams {
datasourceUid: string;
datasourceType: string;
labelName: string;
title?: string;
icon?: IconName;
hidden?: boolean; // If true, the context item will not be shown in the context pills
}Label Value Context Parameters
interface CreateLabelValueContextParams {
datasourceUid: string;
datasourceType: string;
labelName: string;
labelValue: string;
title?: string;
icon?: IconName;
hidden?: boolean; // If true, the context item will not be shown in the context pills
}Structured Data Context Parameters
interface StructuredNodeDataParams {
data: Record<string, any>;
title?: string;
icon?: IconName;
hidden?: boolean; // If true, the context item will not be shown in the context pills
}Component Context Parameters
interface CreateComponentContextParams {
components: Record<string, React.ComponentType<any>>;
prompt: string;
namespace?: string; // Optional: defaults to 'components' if not provided
title?: string;
icon?: IconName;
hidden?: boolean; // If true, the context item will not be shown in the context pills
}Generic Context Parameters
interface NodeDataParams {
id: string;
text?: string;
title?: string;
icon?: IconName;
hidden?: boolean; // If true, the context item will not be shown in the context pills
}Function Extension Types
CallbackFunction
type CallbackFunction = () => FunctionNamespace[];A function that returns an array of function namespaces.
FunctionImplementation
type FunctionImplementation = (...args: any[]) => any;A type for function implementations that can be exposed to the assistant.
NamedFunctions
type NamedFunctions = Record<string, FunctionImplementation>;A record of function names to their implementations.
FunctionNamespace
type FunctionNamespace = {
namespace: string;
functions: NamedFunctions;
};Groups functions under a namespace.
Utility Functions
newFunctionNamespace(namespace: string, functions: NamedFunctions): FunctionNamespace
Creates a new function namespace.
Parameters:
namespace: string- The namespace identifierfunctions: NamedFunctions- The functions to include in the namespace
getExposeAssistantFunctionsConfig(namespaces: FunctionNamespace[]): PluginExtensionAddedFunctionConfig
Creates a plugin extension configuration for exposing functions to the assistant.
Parameters:
namespaces: FunctionNamespace[]- Array of function namespaces to expose
Constants
CALLBACK_EXTENSION_POINT
const CALLBACK_EXTENSION_POINT = 'grafana-assistant-app/callback/v0-alpha';The extension point ID for registering assistant functions.
Additional Exported Types
The package also exports the following types for advanced use cases:
// Data types for context items
export type DashboardNodeData;
export type DatasourceNodeData;
export type FolderNodeData;
export type LabelNameNodeData;
export type LabelValueNodeData;
export type StructuredNodeData;
export type TreeNode;
export type ItemDataType;
// Component types
export type ComponentImplementation;
export type NamedComponents;License
Apache-2.0
