npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@grafana/assistant

v0.1.7

Published

Type definitions and helper functions for Grafana Assistant

Readme

@grafana/assistant

Type definitions and utilities for integrating with the Grafana Assistant.

Installation

npm install @grafana/assistant

Usage

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 available
  • openAssistant?: (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-date
  • loading: boolean - Whether the check is in progress
  • error: string | null - Error message if the check failed, null otherwise
  • acceptTerms: () => 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 URLs
  • initialContext - 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 assistant
  • origin: 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 with createAssistantContextItem
  • autoSend?: boolean - Whether to automatically send the initial prompt (defaults to true)
  • 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 - If true, renders as an icon-only button with tooltip (defaults to false)

<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 changes
  • origin: 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 behavior
  • onComplete?: (text: string) => void - Callback when generation completes successfully
  • onError?: (error: Error) => void - Callback if an error occurs during generation
  • onDelta?: (delta: string) => void - Callback for streaming tokens as they are received during generation
  • disabled?: boolean - Whether the input is disabled
  • className?: string - Additional CSS class name
  • data-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 changes
  • origin: 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 behavior
  • onComplete?: (text: string) => void - Callback when generation completes successfully
  • onError?: (error: Error) => void - Callback if an error occurs during generation
  • onDelta?: (delta: string) => void - Callback for streaming tokens as they are received during generation
  • disabled?: boolean - Whether the textarea is disabled
  • rows?: number - Number of rows for the textarea (defaults to 4)
  • className?: string - Additional CSS class name
  • data-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 progress
  • content - 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:

  1. Terms have been accepted
  2. 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 object
    • origin: 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 assistant
    • context?: ChatContextItem[] - Optional context items to provide additional information to the assistant
    • autoSend?: 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
  • initialContext - Initial array of ChatContextItem to 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 components
  • namespace - A unique identifier for your app's components (e.g., 'myapp', 'datasource')
  • components - A record of component names to their React component implementations
  • urlPattern - 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 URLs
  • initialQuestions - Initial array of Question to 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 URLs
  • initialQuestions - 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 display
  • context - Optional context items to provide
  • autoSend - 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 identifier
  • functions: 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