mirror of https://github.com/grafana/grafana.git
210 lines
8.1 KiB
TypeScript
210 lines
8.1 KiB
TypeScript
/**
|
|
* Configuration file for SQL AI prompts used across expression components
|
|
* NOTE: Schema and error context information integration is planned for future implementation
|
|
*/
|
|
|
|
import { DataQuery } from '@grafana/schema';
|
|
|
|
// Common SQL context information shared across all prompts
|
|
const COMMON_SQL_CONTEXT = {
|
|
engineInfo: 'MySQL dialectic based on dolthub go-mysql-server. The tables are all in memory',
|
|
refIdExplanation: 'RefIDs (A, B, C, etc.) represent data from other queries',
|
|
columnInfo: 'value should always be represented as __value__',
|
|
} as const;
|
|
|
|
// Template placeholders used in prompts
|
|
const TEMPLATE_PLACEHOLDERS = {
|
|
refIds: '{refIds}',
|
|
currentQuery: '{currentQuery}',
|
|
queryInstruction: '{queryInstruction}',
|
|
schemaInfo: '{schemaInfo}', // Note: Schema information will be implemented in future updates
|
|
errorContext: '{errorContext}', // Note: Error context will be implemented in future updates
|
|
queryContext: '{queryContext}',
|
|
} as const;
|
|
|
|
export interface QueryUsageContext {
|
|
panelId?: string;
|
|
alerting?: boolean;
|
|
queries?: DataQuery[];
|
|
dashboardContext?: {
|
|
dashboardTitle?: string;
|
|
panelName?: string;
|
|
};
|
|
datasources?: string[];
|
|
totalRows?: number;
|
|
requestTime?: number;
|
|
numberOfQueries?: number;
|
|
seriesData?: unknown;
|
|
}
|
|
|
|
/**
|
|
* System prompt for SQL suggestion generation with enhanced context
|
|
*/
|
|
const SQL_SUGGESTION_SYSTEM_PROMPT = `You are a SQL expert for Grafana expressions specializing in time series data analysis.
|
|
IMPORTANT - Current SQL Errors (if any): ${TEMPLATE_PLACEHOLDERS.errorContext}
|
|
|
|
SQL dialect required by Grafana expressions: ${COMMON_SQL_CONTEXT.engineInfo}
|
|
|
|
RefIDs context: ${COMMON_SQL_CONTEXT.refIdExplanation}
|
|
Grafana specific context: ${COMMON_SQL_CONTEXT.columnInfo}
|
|
|
|
Available RefIDs to use in composable queries: ${TEMPLATE_PLACEHOLDERS.refIds}
|
|
|
|
Current query to be improved: ${TEMPLATE_PLACEHOLDERS.currentQuery}
|
|
|
|
Schema information to use in composable queries: ${TEMPLATE_PLACEHOLDERS.schemaInfo}
|
|
|
|
${TEMPLATE_PLACEHOLDERS.queryContext}
|
|
|
|
Query instruction: ${TEMPLATE_PLACEHOLDERS.queryInstruction}
|
|
|
|
You may be able to derive schema information from the series data in queryContext.
|
|
|
|
Given the above data, help users with their SQL query by:
|
|
- **PRIORITY: If there are errors listed above, focus on fixing them first**
|
|
- Fixing syntax errors using available field and data type information
|
|
- Suggesting optimal queries based on actual data schema and patterns.
|
|
- Look at query context stats: totalRows, requestTime, numberOfQueries, and if it looks like performance should be part of the conversation, suggest optimizing for performance. Note indexing is not supported in Grafana expressions.
|
|
- Leveraging time series patterns and Grafana-specific use cases
|
|
|
|
Guidelines:
|
|
- Use proper field names and types based on schema information
|
|
- Include LIMIT clauses for performance unless aggregating
|
|
- Consider time-based filtering and grouping for time series data
|
|
- Suggest meaningful aggregations for metric data
|
|
- Use appropriate JOIN conditions when correlating multiple RefIDs
|
|
`;
|
|
|
|
/**
|
|
* System prompt for SQL explanation generation with enhanced context
|
|
*/
|
|
const SQL_EXPLANATION_SYSTEM_PROMPT = `You are an expert in SQL and Grafana SQL expressions with deep knowledge of time series data.
|
|
|
|
SQL dialect: ${COMMON_SQL_CONTEXT.engineInfo}
|
|
|
|
RefIDs: ${COMMON_SQL_CONTEXT.refIdExplanation}
|
|
|
|
Grafana specific context: ${COMMON_SQL_CONTEXT.columnInfo}
|
|
|
|
Available RefIDs: ${TEMPLATE_PLACEHOLDERS.refIds}
|
|
|
|
Schema: ${TEMPLATE_PLACEHOLDERS.schemaInfo}
|
|
|
|
${TEMPLATE_PLACEHOLDERS.queryContext}
|
|
|
|
Explain SQL queries clearly and concisely, focusing on:
|
|
- What data is being selected and from which RefIDs
|
|
- How the data is being transformed or aggregated
|
|
- The purpose and business meaning of the query using dashboard and panel name from query context if relevant
|
|
- Performance implications and optimization opportunities. Database columns can not be indexed in context of Grafana sql expressions. Don't focus on
|
|
performance unless the query context has a requestTime or totalRows that looks like it could benefit from it.
|
|
- Time series specific patterns and their significance
|
|
|
|
Provide a clear explanation of what this SQL query does:`;
|
|
|
|
/**
|
|
* Generate query context text for prompts
|
|
*/
|
|
const generateQueryContext = (queryContext?: QueryUsageContext): string => {
|
|
if (!queryContext) {
|
|
return '';
|
|
}
|
|
|
|
const contextParts = [];
|
|
if (queryContext.panelId) {
|
|
contextParts.push(
|
|
`Panel Type: ${queryContext.panelId}. Please use this to generate suggestions that are relevant to the panel type.`
|
|
);
|
|
}
|
|
if (queryContext.alerting) {
|
|
contextParts.push(
|
|
'Context: Alerting rule (focus on boolean/threshold results). Please use this to generate suggestions that are relevant to the alerting rule.'
|
|
);
|
|
}
|
|
if (queryContext.queries) {
|
|
const queriesText = Array.isArray(queryContext.queries)
|
|
? JSON.stringify(queryContext.queries, null, 2)
|
|
: String(queryContext.queries);
|
|
contextParts.push(`Queries available to use in the SQL Expression: ${queriesText}`);
|
|
}
|
|
if (queryContext.dashboardContext) {
|
|
const dashboardText =
|
|
typeof queryContext.dashboardContext === 'object'
|
|
? JSON.stringify(queryContext.dashboardContext, null, 2)
|
|
: String(queryContext.dashboardContext);
|
|
contextParts.push(`Dashboard context (dashboard title and panel name): ${dashboardText}`);
|
|
}
|
|
if (queryContext.datasources) {
|
|
const datasourcesText = Array.isArray(queryContext.datasources)
|
|
? JSON.stringify(queryContext.datasources, null, 2)
|
|
: String(queryContext.datasources);
|
|
contextParts.push(`Datasources available to use in the SQL Expression: ${datasourcesText}`);
|
|
}
|
|
if (queryContext.totalRows) {
|
|
contextParts.push(`Total rows in the query: ${queryContext.totalRows}`);
|
|
}
|
|
if (queryContext.requestTime) {
|
|
contextParts.push(`Request time: ${queryContext.requestTime}`);
|
|
}
|
|
if (queryContext.numberOfQueries) {
|
|
contextParts.push(`Number of queries: ${queryContext.numberOfQueries}`);
|
|
}
|
|
if (queryContext.seriesData) {
|
|
const seriesDataText =
|
|
typeof queryContext.seriesData === 'object'
|
|
? JSON.stringify(queryContext.seriesData, null, 2)
|
|
: String(queryContext.seriesData);
|
|
contextParts.push(`Series data: ${seriesDataText}`);
|
|
}
|
|
|
|
return contextParts.length
|
|
? `Query Context:
|
|
${contextParts.join('\n')}`
|
|
: '';
|
|
};
|
|
|
|
/**
|
|
* Enhanced interface for prompt generation variables
|
|
*/
|
|
export interface SQLPromptVariables {
|
|
refIds: string;
|
|
currentQuery: string;
|
|
queryInstruction: string;
|
|
schemas?: unknown; // Reserved for future schema implementation
|
|
errorContext?: string[];
|
|
queryContext?: QueryUsageContext;
|
|
}
|
|
|
|
/**
|
|
* Generate the complete system prompt for SQL suggestions with enhanced context
|
|
*
|
|
* Note: Schema information integration is planned for future implementation
|
|
*/
|
|
export const getSQLSuggestionSystemPrompt = (variables: SQLPromptVariables): string => {
|
|
const queryContext = generateQueryContext(variables.queryContext);
|
|
const schemaInfo = ''; // Placeholder for future schema information
|
|
const errorContext = variables.errorContext?.length
|
|
? variables.errorContext.join('\n')
|
|
: 'No current errors detected.';
|
|
|
|
return SQL_SUGGESTION_SYSTEM_PROMPT.replaceAll(TEMPLATE_PLACEHOLDERS.refIds, variables.refIds)
|
|
.replaceAll(TEMPLATE_PLACEHOLDERS.currentQuery, variables.currentQuery)
|
|
.replaceAll(TEMPLATE_PLACEHOLDERS.queryInstruction, variables.queryInstruction)
|
|
.replaceAll(TEMPLATE_PLACEHOLDERS.schemaInfo, schemaInfo)
|
|
.replaceAll(TEMPLATE_PLACEHOLDERS.errorContext, errorContext)
|
|
.replaceAll(TEMPLATE_PLACEHOLDERS.queryContext, queryContext);
|
|
};
|
|
|
|
/**
|
|
* Generate the complete system prompt for SQL explanations with enhanced context
|
|
*/
|
|
export const getSQLExplanationSystemPrompt = (variables: Omit<SQLPromptVariables, 'queryInstruction'>): string => {
|
|
const queryContext = generateQueryContext(variables.queryContext);
|
|
|
|
const schemaInfo = ''; // Placeholder for future schema information
|
|
|
|
return SQL_EXPLANATION_SYSTEM_PROMPT.replaceAll(TEMPLATE_PLACEHOLDERS.refIds, variables.refIds)
|
|
.replaceAll(TEMPLATE_PLACEHOLDERS.schemaInfo, schemaInfo)
|
|
.replaceAll(TEMPLATE_PLACEHOLDERS.queryContext, queryContext);
|
|
};
|