mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Auto-generate: Update generation character limits, improve generation history UX (#76849)
This commit is contained in:
parent
dd773e74f1
commit
714aec2275
@ -11,6 +11,8 @@ interface GenAIDashDescriptionButtonProps {
|
|||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DASHBOARD_DESCRIPTION_CHAR_LIMIT = 300;
|
||||||
|
|
||||||
const DESCRIPTION_GENERATION_STANDARD_PROMPT =
|
const DESCRIPTION_GENERATION_STANDARD_PROMPT =
|
||||||
'You are an expert in creating Grafana Dashboards.\n' +
|
'You are an expert in creating Grafana Dashboards.\n' +
|
||||||
'Your goal is to write a descriptive and concise dashboard description.\n' +
|
'Your goal is to write a descriptive and concise dashboard description.\n' +
|
||||||
@ -19,7 +21,7 @@ const DESCRIPTION_GENERATION_STANDARD_PROMPT =
|
|||||||
'If the dashboard has no panels, the description should be "Empty dashboard"\n' +
|
'If the dashboard has no panels, the description should be "Empty dashboard"\n' +
|
||||||
'There should be no numbers in the description except where they are important.\n' +
|
'There should be no numbers in the description except where they are important.\n' +
|
||||||
'The dashboard description should not have the dashboard title or any quotation marks in it.\n' +
|
'The dashboard description should not have the dashboard title or any quotation marks in it.\n' +
|
||||||
'The description should be, at most, 140 characters.\n' +
|
`The description should be, at most, ${DASHBOARD_DESCRIPTION_CHAR_LIMIT} characters.\n` +
|
||||||
'Respond with only the description of the dashboard.';
|
'Respond with only the description of the dashboard.';
|
||||||
|
|
||||||
export const GenAIDashDescriptionButton = ({ onGenerate, dashboard }: GenAIDashDescriptionButtonProps) => {
|
export const GenAIDashDescriptionButton = ({ onGenerate, dashboard }: GenAIDashDescriptionButtonProps) => {
|
||||||
|
@ -11,6 +11,8 @@ interface GenAIDashTitleButtonProps {
|
|||||||
onGenerate: (description: string) => void;
|
onGenerate: (description: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DASH_TITLE_CHAR_LIMIT = 50;
|
||||||
|
|
||||||
const TITLE_GENERATION_STANDARD_PROMPT =
|
const TITLE_GENERATION_STANDARD_PROMPT =
|
||||||
'You are an expert in creating Grafana Dashboards.\n' +
|
'You are an expert in creating Grafana Dashboards.\n' +
|
||||||
'Your goal is to write a concise dashboard title.\n' +
|
'Your goal is to write a concise dashboard title.\n' +
|
||||||
@ -19,7 +21,7 @@ const TITLE_GENERATION_STANDARD_PROMPT =
|
|||||||
'If the dashboard has no panels, the title should be "Empty dashboard"\n' +
|
'If the dashboard has no panels, the title should be "Empty dashboard"\n' +
|
||||||
'There should be no numbers in the title.\n' +
|
'There should be no numbers in the title.\n' +
|
||||||
'The dashboard title should not have quotation marks in it.\n' +
|
'The dashboard title should not have quotation marks in it.\n' +
|
||||||
'The title should be, at most, 50 characters.\n' +
|
`The title should be, at most, ${DASH_TITLE_CHAR_LIMIT} characters.\n` +
|
||||||
'Respond with only the title of the dashboard.';
|
'Respond with only the title of the dashboard.';
|
||||||
|
|
||||||
export const GenAIDashTitleButton = ({ onGenerate, dashboard }: GenAIDashTitleButtonProps) => {
|
export const GenAIDashTitleButton = ({ onGenerate, dashboard }: GenAIDashTitleButtonProps) => {
|
||||||
|
@ -16,12 +16,11 @@ import {
|
|||||||
VerticalGroup,
|
VerticalGroup,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
|
|
||||||
import { getFeedbackMessage } from './GenAIPanelTitleButton';
|
|
||||||
import { GenerationHistoryCarousel } from './GenerationHistoryCarousel';
|
import { GenerationHistoryCarousel } from './GenerationHistoryCarousel';
|
||||||
import { QuickFeedback } from './QuickFeedback';
|
import { QuickFeedback } from './QuickFeedback';
|
||||||
import { StreamStatus, useOpenAIStream } from './hooks';
|
import { StreamStatus, useOpenAIStream } from './hooks';
|
||||||
import { AutoGenerateItem, EventTrackingSrc, reportAutoGenerateInteraction } from './tracking';
|
import { AutoGenerateItem, EventTrackingSrc, reportAutoGenerateInteraction } from './tracking';
|
||||||
import { Message, DEFAULT_OAI_MODEL, QuickFeedbackType, sanitizeReply } from './utils';
|
import { getFeedbackMessage, Message, DEFAULT_OAI_MODEL, QuickFeedbackType, sanitizeReply } from './utils';
|
||||||
|
|
||||||
export interface GenAIHistoryProps {
|
export interface GenAIHistoryProps {
|
||||||
history: string[];
|
history: string[];
|
||||||
|
@ -12,6 +12,8 @@ interface GenAIPanelDescriptionButtonProps {
|
|||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PANEL_DESCRIPTION_CHAR_LIMIT = 200;
|
||||||
|
|
||||||
const DESCRIPTION_GENERATION_STANDARD_PROMPT =
|
const DESCRIPTION_GENERATION_STANDARD_PROMPT =
|
||||||
'You are an expert in creating Grafana Panels.\n' +
|
'You are an expert in creating Grafana Panels.\n' +
|
||||||
'You will be given the title and description of the dashboard the panel is in as well as the JSON for the panel.\n' +
|
'You will be given the title and description of the dashboard the panel is in as well as the JSON for the panel.\n' +
|
||||||
@ -19,7 +21,7 @@ const DESCRIPTION_GENERATION_STANDARD_PROMPT =
|
|||||||
'The panel description is meant to explain the purpose of the panel, not just its attributes.\n' +
|
'The panel description is meant to explain the purpose of the panel, not just its attributes.\n' +
|
||||||
'Do not refer to the panel; simply describe its purpose.\n' +
|
'Do not refer to the panel; simply describe its purpose.\n' +
|
||||||
'There should be no numbers in the description except for thresholds.\n' +
|
'There should be no numbers in the description except for thresholds.\n' +
|
||||||
'The description should be, at most, 140 characters.';
|
`The description should be, at most, ${PANEL_DESCRIPTION_CHAR_LIMIT} characters.`;
|
||||||
|
|
||||||
export const GenAIPanelDescriptionButton = ({ onGenerate, panel }: GenAIPanelDescriptionButtonProps) => {
|
export const GenAIPanelDescriptionButton = ({ onGenerate, panel }: GenAIPanelDescriptionButtonProps) => {
|
||||||
const messages = React.useMemo(() => getMessages(panel), [panel]);
|
const messages = React.useMemo(() => getMessages(panel), [panel]);
|
||||||
@ -48,7 +50,7 @@ function getMessages(panel: PanelModel): Message[] {
|
|||||||
role: Role.system,
|
role: Role.system,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: `The panel is part of a dashboard with the description: ${dashboard.title}`,
|
content: `The panel is part of a dashboard with the description: ${dashboard.description}`,
|
||||||
role: Role.system,
|
role: Role.system,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -5,17 +5,19 @@ import { PanelModel } from '../../state';
|
|||||||
|
|
||||||
import { GenAIButton } from './GenAIButton';
|
import { GenAIButton } from './GenAIButton';
|
||||||
import { EventTrackingSrc } from './tracking';
|
import { EventTrackingSrc } from './tracking';
|
||||||
import { Message, QuickFeedbackType, Role } from './utils';
|
import { Message, Role } from './utils';
|
||||||
|
|
||||||
interface GenAIPanelTitleButtonProps {
|
interface GenAIPanelTitleButtonProps {
|
||||||
onGenerate: (title: string) => void;
|
onGenerate: (title: string) => void;
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PANEL_TITLE_CHAR_LIMIT = 50;
|
||||||
|
|
||||||
const TITLE_GENERATION_STANDARD_PROMPT =
|
const TITLE_GENERATION_STANDARD_PROMPT =
|
||||||
'You are an expert in creating Grafana Panels.' +
|
'You are an expert in creating Grafana Panels.' +
|
||||||
'Your goal is to write short, descriptive, and concise panel title for a panel.' +
|
'Your goal is to write short, descriptive, and concise panel title.' +
|
||||||
'The title should be shorter than 50 characters.';
|
`The title should be shorter than ${PANEL_TITLE_CHAR_LIMIT} characters.`;
|
||||||
|
|
||||||
export const GenAIPanelTitleButton = ({ onGenerate, panel }: GenAIPanelTitleButtonProps) => {
|
export const GenAIPanelTitleButton = ({ onGenerate, panel }: GenAIPanelTitleButtonProps) => {
|
||||||
const messages = React.useMemo(() => getMessages(panel), [panel]);
|
const messages = React.useMemo(() => getMessages(panel), [panel]);
|
||||||
@ -44,21 +46,12 @@ function getMessages(panel: PanelModel): Message[] {
|
|||||||
role: Role.system,
|
role: Role.system,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: `The panel is part of a dashboard with the description: ${dashboard.title}`,
|
content: `The panel is part of a dashboard with the description: ${dashboard.description}`,
|
||||||
role: Role.system,
|
role: Role.system,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
content: `Use this JSON object which defines the panel: ${JSON.stringify(panel.getSaveModel())}`,
|
content: `Use this JSON object which defines the panel: ${JSON.stringify(panel.getSaveModel())}`,
|
||||||
role: Role.user,
|
role: Role.system,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getFeedbackMessage = (previousResponse: string, feedback: string | QuickFeedbackType): Message[] => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
role: Role.system,
|
|
||||||
content: `Your previous response was: ${previousResponse}. The user has provided the following feedback: ${feedback}. Re-generate your response according to the provided feedback.`,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
@ -51,5 +51,6 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
gap: 16,
|
gap: 16,
|
||||||
|
userSelect: 'none',
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
@ -65,6 +65,21 @@ export async function isLLMPluginEnabled() {
|
|||||||
return llms.openai.enabled().then((response) => response.ok);
|
return llms.openai.enabled().then((response) => response.ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the message to be sent to OpenAI to generate a new response.
|
||||||
|
* @param previousResponse
|
||||||
|
* @param feedback
|
||||||
|
* @returns Message[] to be sent to OpenAI to generate a new response
|
||||||
|
*/
|
||||||
|
export const getFeedbackMessage = (previousResponse: string, feedback: string | QuickFeedbackType): Message[] => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
role: Role.system,
|
||||||
|
content: `Your previous response was: ${previousResponse}. The user has provided the following feedback: ${feedback}. Re-generate your response according to the provided feedback.`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param dashboard Dashboard to generate a title or description for
|
* @param dashboard Dashboard to generate a title or description for
|
||||||
|
Loading…
Reference in New Issue
Block a user