SeemGen/Models/AiPrompts.cs

359 lines
24 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using BLAIzor.Services;
using System.Text;
namespace BLAIzor.Models
{
public static class AiPrompts
{
public static class WelcomeContent
{
public static string GetSystemMessageForWelcomeMessage(string mood, string siteEntity, string extractedText, string selectedBrandName, string language, string menuList)
{
string systemMessage = "You are a helpful, " + mood + " assistant that welcomes the user speaking in the name of the " + siteEntity + " described by the content, on a website of " + selectedBrandName + " in " + language + ". Use the following content: `" +
extractedText + "` " +
//"and generate a short" +Mood+ "but kind marketing-oriented welcome message and introduction of the brand for the user, constructed as simple Bootstrap HTML codeblock with a <h1> tagged title and a paragraph." +
"and generate a" + mood + " marketing-oriented welcome message and a summary of the content and introduction " +
"of the brand for the user in the name of " + siteEntity + " , aiming to explain clearly, what does the company/person offer, constructed " +
"as simple Bootstrap HTML <div clss=\"container\"> codeblock with a <h1> tagged title and a paragraph." +
"If there is any logo, or not logo but main brand image in the document use that url, " +
"and add that in a new container, as a bootstrap responsive ('img-fluid py-3') image, with the maximum height of 30vh." +
"If there is anything marked important in the text, make sure to add that in your answer." +
"If there are links to be displayed, make sure to display them as clickable links." +
"After the welcome message, always add in a new div with container class: 'This website has a live, " +
"AI interface: if you have any questions, you can simply ask either by typing in the message " +
"box, or by clicking the microphone icon on the top of the page. '" +
"Here is a list of topics " + menuList +
", make a new bootstrap clearfix and after that make a clickable bootstrap " +
"styled (btn btn-primary) button from each of the determined topics, " +
"that calls the javascript function 'callAI({the name of the topic})' on click. " +
"Do not include anything else than the html title and text elements, no css, no scripts, no head or other tags." +
"Do not mark your answer with ```html or any other mark.";
return systemMessage;
}
}
public static class UserIntention
{
}
public static class ContentProcessing
{
public static string GetSystemMessageForJsonResultDecision(string language, string extractedText, string currentDom)
{
string systemMessage = $"You are a helpful assistant built in a website, trying to figure out what the User wants to do or know about.\r\n" +
"Your job is to classify the user's request into one of the following categories:\r\n" +
"1. **Ask about or search infromation in the websites content** (Return a 'Text result')\r\n" +
"2. **Analyze the currently displayed HTML content** (Return an 'Examination result')\r\n" +
"3. **Initiate an action** (Return a 'Method result')\r\n" +
"If none of the above applies, return an 'Error result'.\r\n\r\n" +
"**Response format:**\r\n" +
"Strictly respond in " + language + " as a JSON object, using one of the following formats:\r\n" +
"1. **chatGPTMethodResult** (for initiating actions):\r\n" +
" - `type`: \"methodresult\"\r\n" +
" - `text`: A short explanation of what the user wants to do.\r\n" +
" - `methodToCall`: One of: [openContactForm, openCalendar, openApplicationForm]\r\n" +
" - `parameter`: [email address for openContactForm, calendlyUserName for openCalendar, empty string for openApplicationForm]\r\n\r\n" +
"2. **chatGPTTextResult** (for general website content searches):\r\n" +
" - `type`: \"textresult\"\r\n" +
" - `text`: The users unmodified query.\r\n\r\n" +
"3. **chatGPTExaminationResult** (for analyzing the currently displayed page only):\r\n" +
" - `type`: \"examinationresult\"\r\n" +
" - `text`: The users unmodified query.\r\n\r\n" +
"4. **chatGPTErrorResult** (for errors):\r\n" +
" - `type`: \"errorresult\"\r\n" +
" - `text`: A description of the issue encountered.\r\n\r\n" +
"**Decision Rules:**\r\n" +
"- If the user is **searching for website content** beyond what is currently displayed (e.g., 'Find information about our services'), return a `textresult`.\r\n" +
"- If the user is **asking about the currently visible content** (e.g., 'What is shown on the page?'), return an `examinationresult`.\r\n" +
"- If the user wants to **perform an action**, return a `methodresult`.\r\n" +
"- If the required parameter is missing, return an `errorresult`.\r\n\r\n" +
"**Examples:**\r\n" +
"- User asks: 'Show me information about pricing' → `textresult`\r\n" +
"- User asks: 'What is displayed right now?' → `examinationresult`\r\n" +
"- User asks: 'Open the contact form' → `methodresult`\r\n" +
"- User asks: 'Contact support' but no email is found → `errorresult`\r\n\r\n" +
"**Context:**\r\n" +
"- Base responses on this initial document: {" + extractedText + "}\r\n" +
"- Current displayed HTML: {" + currentDom + "}\r\n" +
"**IMPORTANT:**\r\n" +
"- If the request is about general content, **DO NOT use 'examinationresult'**.\r\n" +
"- If the request is about the currently displayed page, **DO NOT use 'textresult'**.\r\n" +
"- Do NOT format the response with markdown, code blocks, or `json` tags, do not add any title, or explanation besides the plain json object";
return systemMessage;
}
}
public static class HtmlGeneration
{
public const string BootstrapCard = "Generate a Bootstrap 5 card layout using the following content:";
public const string SectionLayout = "Create a responsive HTML5 layout section for this text:";
}
public static class LayoutPlanning
{
public static string GetLayoutPlanningSystemPrompt(List<HtmlSnippet> htmlToUse, Dictionary<string, string>? photos, string[]? topics)
{
var sb = new StringBuilder();
// 📌 STRICT FORMAT INSTRUCTION
sb.AppendLine("You are a helpful assistant whose ONLY task is to break down THE PROVIDED CONTENT into a structured JSON object for Bootstrap 5 pages, using \n" +
"**layoutplan**:\r\n" +
"- `title`: \"The title of the page\"\r\n" +
"- `blocks`: \"an array of layoutblocks\"\r\n" +
".");
if ((htmlToUse != null))
{
sb.AppendLine("\n### You have these html snippets provided:");
foreach (var snippet in htmlToUse)
{
//no need to paste the html code
//sb.AppendLine($"Snippet id: {snippet.Id}, Snippet name: {snippet.Name}, Snippet description: {snippet.Description}, Snippet type: {snippet.Type}, Snippet template code: {snippet.Html}");
sb.AppendLine($"Snippet id: {snippet.Id}, Snippet name: {snippet.Name}, Snippet description: {snippet.Description}, Snippet type: {snippet.Type}");
}
sb.AppendLine("- Use them ONLY if relevant.");
}
if (photos != null && photos.Any())
{
sb.AppendLine("\n### Photos to be used in the blocks:");
sb.AppendLine(string.Join(", ", photos.Select(kv => $"{kv.Key}: {kv.Value}")));
}
if (topics != null && topics.Any())
{
sb.AppendLine("\n### Topics:");
sb.AppendLine(string.Join(", ", topics));
}
sb.AppendLine("### ⛔️ ABSOLUTELY DO NOT:");
sb.AppendLine("- ❌ Return HTML structure trees like `<section><div>`...");
sb.AppendLine("- ❌ Include keys like `src`, `alt`, `url`, `items`, or nested object lists.");
sb.AppendLine("- ❌ Invent block types not on the list.");
sb.AppendLine("- ❌ Return any explanation, markdown, prose, comments, or fallback formats.");
sb.AppendLine("- ❌ Use any of these block types: `image`, `quote`, `list`, `layout`, `header`, `footer`, `sidebar`, etc.");
sb.AppendLine("- ❌ Remove messages for AI marked with []");
sb.AppendLine("\n### ✅ REQUIRED OUTPUT FORMAT:");
sb.AppendLine("{");
sb.AppendLine(" \"title\": \"string\",");
sb.AppendLine(" \"blocks\": [");
sb.AppendLine(" { \"type\": \"string\", \"rawcontent\": \"string (text)\", \"preferredsnippetid\" : an integer id of matching html snippet if one found., \"order\": an incremented integer to set the blocks in order }");
sb.AppendLine(" ]");
sb.AppendLine("}");
sb.AppendLine("\n### ✅ Allowed `type` values (only use these):");
sb.AppendLine("- hero");
sb.AppendLine("- text");
sb.AppendLine("- text-image");
sb.AppendLine("- features");
sb.AppendLine("- cta");
sb.AppendLine("- video");
sb.AppendLine("- icon-list");
sb.AppendLine("- event-list");
sb.AppendLine("- audio-player");
sb.AppendLine("- topic-buttons");
sb.AppendLine("\n### ❗ GOOD EXAMPLE:");
sb.AppendLine("{");
sb.AppendLine(" \"title\": \"Welcome to Our Product\",");
sb.AppendLine(" \"blocks\": [");
sb.AppendLine(" { \"type\": \"hero\", \"rawcontent\": \"Example text\", \"preferredsnippetid\": 1, \"order\": 0 },");
sb.AppendLine(" { \"type\": \"features\", \"rawcontent\": \"Example features\", \"order\": 1 },");
sb.AppendLine(" { \"type\": \"cta\", \"rawcontent\": \"call to action content\", \"order\": 2 }");
sb.AppendLine(" ]");
sb.AppendLine("}");
sb.AppendLine("\n### ⛔ BAD EXAMPLES (DO NOT DO THIS):");
sb.AppendLine("- { \"type\": \"image\", \"src\": \"...\", \"alt\": \"...\" }");
sb.AppendLine("- { \"type\": \"list\", \"items\": [\"...\", \"...\"] }");
sb.AppendLine("- { \"layout\": { \"header\": ..., \"footer\": ... } }");
sb.AppendLine("\n### FINAL TASK:");
sb.AppendLine("Based on the following content, generate a JSON object following the exact format above. Output only the JSON. No markdown. No other marks. No explanation. ONLY the pure JSON.");
return sb.ToString();
}
public static string GetLayoutPlanningUserPrompt(string interMediateResult, string pageTitle, Dictionary<string, string>? photos)
{
var userMessage = "Based on the following content:\n\n*** " + interMediateResult + " ***\n\n" +
"and the available photos:";
if (photos != null && photos.Any())
{
userMessage += "\n### Photo urls to be used WITHOUT ANY MODIFICATION in the blocks:";
userMessage += string.Join(", ", photos.Select(kv => $"{kv.Key}: {kv.Value}"));
}
userMessage += ", return ONLY a JSON object representing a structured content layout for a webpage with the title '" + pageTitle + "', with this exact shape:\n" +
"{ \"title\": string, \"blocks\": [ { \"type\": \"string\", \"rawcontent\": \"string (text)\", \"preferredsnippetid\" : an integer id of matching html snippet if one found., \"order\": an incremented integer to set the blocks in order } ] }\n\n" +
"⚠️ DO NOT use layout structures like 'header', 'sidebar', 'mainContent', or 'footer'.\n" +
"⚠️ DO NOT explain anything. Just return the pure JSON. No markdown, no ``` markers.\n\n" +
"🎯 OBJECTIVE:\n" +
"1. Determine 1 to 5 major content blocks from the input, grouping full paragraphs or sections together.\n" +
"Prefer **1 to 5 blocks max**, unless the content is extremely long. Each block should represent a semantically complete section.\r\n" +
"Group related ideas into one block, even if they are multiple paragraphs. Do NOT break up content just because it is a new sentence. \r\n" +
"2. Use meaningful, semantically grouped layout block types like: 'hero', 'features list', 'text with image', 'text', 'product list', 'call to action', 'videoplayer', 'audioplayer', etc.\n" +
"3. Each block should contain **rich content** and related photo ['photo url': 'the url of the photo'], not just one or two sentences. Group related ideas into a single `rawcontent` field.\n\n" +
"DO NOT REMOVE ANY URLS (photo, wen link, etc) from the section or paragraph that it follows. \n\n" +
"📌 Examples of good block grouping:\n" +
"- All introductory marketing text together in one 'hero' or 'text' block\n" +
"- A group of benefits or features into a single 'features' block\n" +
"- A pitch paragraph into a 'call to action' block\n\n" +
"🎨 Naming:\n" +
"- Try to find related type values in the available snippets list. If you find a relevant snippet for that block, use the name of that snippet for type, and add the id if the snippet as preferredsnippetid." +
"- If there is no relevant snippet, use such layout `type` values: hero, text, features, text with image, call to action, product list, team members, testimonial, event list, blogpost, article, video player, audio player, etc\n" +
"X Restrictions:" +
"- DO **NOT** modify the photo urls in any way." +
"- DO **NOT use the same text multiple times**" +
"- Do **NOT** generate or assume new photo URLs.\n" +
"- Do **NOT** modify photo URLs in any way.\n" +
"- Do **NOT** skip or deny ANY part of the provided text. All of the provided text should be put in blocks \n" +
"- Do **NOT** assume ANY content, like missing prices, missing links, etc. \n" +
"✅ Final output: JSON only, well grouped, no extra explanation or formatting, no markdown, no ``` markers.\n";
return userMessage;
}
}
public static class HtmlRendering
{
public static string GetHtmlRenderingSystemPromptForTextAndErrorResult(string language, string pageTitle, List<HtmlSnippet> htmlToUse, Dictionary<string, string>? photos, string[]? topics)
{
var sb = new StringBuilder($"You are a helpful assistant generating HTML in {language} using Bootstrap 5.\n\n" +
"### General Instructions:\n" +
"- Output only the **HTML content** between the menu and footer.\n" +
"- DO NOT include `<head>`, `<body>`, or markdown formatting.\n" +
"- Use `<h1 class='p-3'>` for the title: " + pageTitle + ".\n" +
"- Structure sections inside separate `<section>` or `<div class='row'>` blocks.\n" +
"- Use Bootstrap spacing and layout classes:\n" +
" - Use `row justify-content-center` for rows.\n" +
" - Use `col-xx-x` only for multiple-column layouts.\n" +
" - Always use `img-fluid` for images.\n" +
"- Avoid: unnecessary paragraph classes, nesting `<img>` inside `<p>`, or using `col` for single-column content.\n\n");
if (htmlToUse != null && htmlToUse.Any())
{
sb.AppendLine("### Snippet Handling:\n" +
"- You are provided with multiple HTML snippets:\n");
foreach (var snippet in htmlToUse)
{
sb.AppendLine($"{snippet.Id}: {snippet.Name}: {snippet.Html}\n");
sb.AppendLine($"Type: {snippet.Type}, Tags: {snippet.Tags}, Variant: {snippet.Variant}\n");
}
sb.AppendLine(
"- Use each snippet as a separate `<section>`.\n" +
"- DO NOT merge snippets into one block.\n" +
"- Use snippets only if they match the content block.\n" +
"- Prefer variants with images if image content is present.\n" +
"- Always use a short title in `<h>` and place body text in a `<p>`.\n" +
"- If snippet includes a button, wrap it in `<div class='text-center'>`.\n");
}
if (photos != null && photos.Any())
{
sb.AppendLine("### Photo Usage:\n" +
"- Use ONLY the following image URLs as-is (no changes):\n" +
string.Join(", ", photos.Select(kv => $"{kv.Key}: {kv.Value}")) + "\n" +
"- Example:\n" +
$" <img src='{photos.First().Value}' class='img-fluid' alt='{photos.First().Key}' />\n" +
"- DO NOT generate or modify photo URLs.\n");
}
if (topics != null && topics.Any())
{
sb.AppendLine("### Topic Buttons:\n" +
"- Place this section last, titled `Related`.\n" +
"- Generate a `btn btn-primary` for each topic, calling `callAI('{original_non_translated_topicName}')`.\n" +
"- Translate topic names to " + language + " if needed.\n" +
"- Example:\n" +
$" <button class='btn btn-primary' onclick='callAI(\"{topics.FirstOrDefault()}\")'>{topics.FirstOrDefault()}</button>\n");
}
else
{
sb.AppendLine("- No topics provided → DO NOT generate topic buttons.");
}
sb.AppendLine("\n### DO NOT:\n" +
"- DO **NOT** merge different content blocks.\n" +
"- DO **NOT** remove javascript or <script> tags" +
"- DO **NOT** wrap the full output in a single `div`.\n" +
"- DO **NOT** skip any provided content.\n" +
"- DO **NOT** add assumed text (e.g. prices, links).\n" +
"- DO **NOT** add `<img>` if no image URL exists.\n" +
"- DO **NOT** modify image URLs. not even adding 'https://example.com or such before the relaitve path'\n" +
"- DO **NOT** include explanation, markdown, or ` ```html` markers.\n");
return sb.ToString();
}
public static string HtmlRenderingUserPromptForTextAndErrorResult = "Create a perfect, production ready, structured, responsive Bootstrap 5 webpage " +
"content from the provided layout and available html snippets. \r \n" +
"Read the layout plan, analyze the blocks, and identify if there is any matching html snippets for each block folowing these rules: \r \n" +
"- If there is no matching html snippet, generate the bootstrap 5 based layout for the given block. Else parse the block content into the available code snippet." +
"- For each block, add am opening and closing comment with the name of the block like: <!-- Hero start --> \r \n" +
"- Do not remove script tags from the provided snippets. \r \n" +
"If the block's rawcontent contains photo url, display that photo within that section, not elsewhere. ";
public static string GetHtmlRenderingAssistantMessageForTextAndErrorResult(LayoutPlan layoutPlan)
{
string assistantMessage = "`Provided layout plan, that contains the text to be displayed as HTML`:";
foreach (var block in layoutPlan.Blocks)
{
assistantMessage += $"Block type: {block.Type}, block content: {block.RawContent}";
}
return assistantMessage;
}
public static string GetHtmlRenderingSystemPromptForMethodResult(string language, string methodToCall, string methodParameter)
{
var sb = new StringBuilder("You are a helpful assistant generating HTML content in " + language + " using Bootstrap. \n\n" +
"### Rules to Follow: \n" +
"- Please generate clean and structured HTML that goes inside a Bootstrap container.\n" +
"- DO NOT include `<head>`, `<body>` tags — only content inside the Bootstrap container.\n" +
"- Use `<h1 class='p-3'>` for a short title followed by the content, based on the user's query.\n" +
"- Structure content using **separate `row` elements** for different sections.\n" +
"- Use Bootstrap classes to ensure proper spacing and alignment.\n" +
" - Use 'row justify-content-center' for layout, 'col-xx-x' classes for columns (ONLY IF multiple columns are needed), and always use 'img-fluid' class for images.\r\n" +
" - Do NOT use 'col' class if there is only one column to display in the row. \n" +
"- Do NOT use additional class for paragraphs! \n" +
"- Do NOT nest images inside paragraphs! \n" +
"- Ensure clear **separation of content into multiple sections if multiple snippets are provided**.\n");
if (!string.IsNullOrEmpty(methodToCall))
{
sb.AppendLine("- At the END of the content, include a **single** Bootstrap button (`btn btn-primary`) that calls `" + methodToCall + "` with `" + methodParameter + "` on click.\n");
}
sb.AppendLine("- DO **NOT** merge different content sections.\n" +
"- DO **NOT** wrap the entire content in a single `div`— use separate `row` divs.\n" +
"- Do **NOT** skip or deny ANY part of the provided text. All of the provided text should be displayed as html\n" +
"- Do **NOT** assume ANY content, like missing prices, missing links. \n" +
"- If the snippet contains an image, but there is no photo url available, SKIP adding the image tag." +
"- **Never** add explanations or start with ```html syntax markers.\n");
return sb.ToString();
}
}
}
}