mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
	
	
		
			123 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
		
		
			
		
	
	
			123 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
|  | import { useCallback } from 'react'; | ||
|  | 
 | ||
|  | import { t } from '@grafana/i18n'; | ||
|  | 
 | ||
|  | import { GenAIButton } from '../../../dashboard/components/GenAI/GenAIButton'; | ||
|  | import { EventTrackingSrc } from '../../../dashboard/components/GenAI/tracking'; | ||
|  | import { Message, Role } from '../../../dashboard/components/GenAI/utils'; | ||
|  | 
 | ||
|  | import { getSQLSuggestionSystemPrompt, QueryUsageContext } from './sqlPromptConfig'; | ||
|  | 
 | ||
|  | interface GenAISQLSuggestionsButtonProps { | ||
|  |   currentQuery: string; | ||
|  |   onGenerate: (suggestion: string) => void; | ||
|  |   onHistoryUpdate?: (history: string[]) => void; | ||
|  |   refIds: string[]; | ||
|  |   initialQuery: string; | ||
|  |   schemas?: unknown; // Reserved for future schema implementation
 | ||
|  |   errorContext?: string[]; | ||
|  |   queryContext?: QueryUsageContext; | ||
|  | } | ||
|  | 
 | ||
|  | // AI prompts for different SQL use cases
 | ||
|  | 
 | ||
|  | const getContextualPrompts = (refIds: string[], currentQuery: string): string[] => { | ||
|  |   const trimmedQuery = currentQuery.trim(); | ||
|  | 
 | ||
|  |   // If there's a current query, focus more on fixing/improving it
 | ||
|  |   if (trimmedQuery) { | ||
|  |     return [`Improve, fix syntax errors, or optimize this SQL query: ${trimmedQuery}`]; | ||
|  |   } | ||
|  | 
 | ||
|  |   // If no current query, focus on suggestions
 | ||
|  |   return [ | ||
|  |     `Join, aggregate, filter, calculate percentiles, create time-based 
 | ||
|  |     window functions, or generally just make common SQL pattern queries for data from ${refIds.join(', ')}`,
 | ||
|  |   ]; | ||
|  | }; | ||
|  | 
 | ||
|  | /** | ||
|  |  * Creates messages for the LLM to generate SQL suggestions | ||
|  |  * | ||
|  |  * @param refIds - The list of RefIDs available in the current context | ||
|  |  * @param currentQuery - The current SQL query being edited | ||
|  |  * @param schemas - Optional schema information (planned for future implementation) | ||
|  |  * @param errorContext - Optional error context for targeted fixes (planned for future implementation) | ||
|  |  * @param queryContext - Optional query usage context | ||
|  |  * @returns A list of messages to be sent to the LLM for generating SQL suggestions | ||
|  |  */ | ||
|  | const getSQLSuggestionMessages = ( | ||
|  |   refIds: string[], | ||
|  |   currentQuery: string, | ||
|  |   schemas?: unknown, | ||
|  |   errorContext?: string[], | ||
|  |   queryContext?: QueryUsageContext | ||
|  | ): Message[] => { | ||
|  |   const trimmedQuery = currentQuery.trim(); | ||
|  |   const queryInstruction = trimmedQuery | ||
|  |     ? 'Focus on fixing, improving, or enhancing the current query provided above.' | ||
|  |     : 'Generate a new SQL query based on the available RefIDs and common use cases.'; | ||
|  | 
 | ||
|  |   const systemPrompt = getSQLSuggestionSystemPrompt({ | ||
|  |     refIds: refIds.length > 0 ? refIds.join(', ') : 'A', | ||
|  |     currentQuery: trimmedQuery || 'No current query provided', | ||
|  |     queryInstruction: queryInstruction, | ||
|  |     schemas, // Will be utilized once schema extraction is implemented
 | ||
|  |     errorContext, | ||
|  |     queryContext, | ||
|  |   }); | ||
|  | 
 | ||
|  |   const contextualPrompts = getContextualPrompts(refIds, currentQuery); | ||
|  |   const selectedPrompt = contextualPrompts[Math.floor(Math.random() * contextualPrompts.length)]; | ||
|  | 
 | ||
|  |   return [ | ||
|  |     { | ||
|  |       role: Role.system, | ||
|  |       content: systemPrompt, | ||
|  |     }, | ||
|  |     { | ||
|  |       role: Role.user, | ||
|  |       content: selectedPrompt, | ||
|  |     }, | ||
|  |   ]; | ||
|  | }; | ||
|  | 
 | ||
|  | export const GenAISQLSuggestionsButton = ({ | ||
|  |   currentQuery, | ||
|  |   onGenerate, | ||
|  |   onHistoryUpdate, | ||
|  |   refIds, | ||
|  |   initialQuery, | ||
|  |   schemas, // Future implementation will use this for enhanced context
 | ||
|  |   errorContext, | ||
|  |   queryContext, | ||
|  | }: GenAISQLSuggestionsButtonProps) => { | ||
|  |   const messages = useCallback(() => { | ||
|  |     return getSQLSuggestionMessages(refIds, currentQuery, schemas, errorContext, queryContext); | ||
|  |   }, [refIds, currentQuery, schemas, errorContext, queryContext]); | ||
|  | 
 | ||
|  |   const text = !currentQuery || currentQuery === initialQuery ? 'Generate suggestion' : 'Improve query'; | ||
|  | 
 | ||
|  |   return ( | ||
|  |     <GenAIButton | ||
|  |       disabled={refIds.length === 0} | ||
|  |       eventTrackingSrc={EventTrackingSrc.sqlExpressions} | ||
|  |       messages={messages} | ||
|  |       onGenerate={onGenerate} | ||
|  |       onHistoryChange={onHistoryUpdate} | ||
|  |       temperature={0.3} | ||
|  |       text={t('sql-expressions.sql-ai-interaction', `{{text}}`, { text })} | ||
|  |       timeout={60000} // 60 seconds
 | ||
|  |       toggleTipTitle={t('sql-expressions.ai-suggestions-title', 'AI-powered SQL expression suggestions')} | ||
|  |       tooltip={ | ||
|  |         refIds.length === 0 | ||
|  |           ? t('sql-expressions.add-query-tooltip', 'Add at least one data query to generate SQL suggestions') | ||
|  |           : t( | ||
|  |               'expressions.sql-expr.tooltip-experimental', | ||
|  |               'SQL Expressions LLM integration is experimental. Please report any issues to the Grafana team.' | ||
|  |             ) | ||
|  |       } | ||
|  |     /> | ||
|  |   ); | ||
|  | }; |