Add AI prompts

This part will be highly reworked soon because :
- prompts will come from a remote JSON file
- menu will be build depending of prompts that will contains translations

I think it should also be moved in another module later.
This commit is contained in:
Théo Poizat
2025-12-04 17:03:27 +01:00
committed by Dat H. Pham
parent 29e90f256f
commit b3e111b9bf
3 changed files with 227 additions and 0 deletions
@@ -0,0 +1,78 @@
import '../../presentation/model/ai_action.dart';
import '../../presentation/model/ai_scribe_menu_action.dart';
// TODO
// In a near future, prompts will be loaded from a remote source
class AIPrompts {
static String buildPrompt(AIAction action, String? text) {
return switch (action) {
PredefinedAction(action: final menuAction) => buildPredefinedPrompt(menuAction, text ?? ''),
CustomPromptAction(prompt: final customPrompt) => buildCustomPrompt(customPrompt, text),
};
}
static String buildPredefinedPrompt(AIScribeMenuAction action, String text) {
switch (action) {
case AIScribeMenuAction.correctGrammar:
return correctGrammar(text);
case AIScribeMenuAction.improveMakeShorter:
return improveMakeShorter(text);
case AIScribeMenuAction.improveExpandContext:
return improveExpandContext(text);
case AIScribeMenuAction.improveEmojify:
return improveEmojify(text);
case AIScribeMenuAction.improveTransformToBullets:
return improveTransformToBullets(text);
case AIScribeMenuAction.changeToneProfessional:
return changeToneTo(text, 'professional');
case AIScribeMenuAction.changeToneCasual:
return changeToneTo(text, 'casual');
case AIScribeMenuAction.changeTonePolite:
return changeToneTo(text, 'polite');
case AIScribeMenuAction.translateFrench:
return translateTo(text, 'French');
case AIScribeMenuAction.translateEnglish:
return translateTo(text, 'English');
case AIScribeMenuAction.translateRussian:
return translateTo(text, 'Russian');
case AIScribeMenuAction.translateVietnamese:
return translateTo(text, 'Vietnamese');
}
}
static String improveMakeShorter(String text) {
return 'Make the following text shorter and more concise. Output only the result. Preserve input formatting. Text:\n\n$text';
}
static String improveExpandContext(String text) {
return 'Expand the context of the following text to make it more detailed and comprehensive. Output only the result. Preserve input formatting. Text:\n\n$text';
}
static String improveEmojify(String text) {
return 'Add appropriate emojis to the following text to make it more expressive. Output only the result. Preserve input formatting. Text:\n\n$text';
}
static String improveTransformToBullets(String text) {
return 'Transform the following text into a bulleted list format. Output only the result. Preserve input formatting. Text:\n\n$text';
}
static String correctGrammar(String text) {
return 'Correct grammar of the following text. Output only the result. Preserve input formatting. Text:\n\n$text';
}
static String changeToneTo(String text, String tone) {
return 'Change the tone of the following text to be more $tone. Output only the result. Preserve input formatting. Text:\n\n$text';
}
static String translateTo(String text, String language) {
return 'Translate the following text to $language. Output only the result. Preserve input formatting. Text:\n\n$text';
}
static String buildCustomPrompt(String customPrompt, String? text) {
if (text == null) {
return customPrompt;
}
return '$customPrompt\n\nText:\n\n$text';
}
}
@@ -0,0 +1,25 @@
import 'ai_scribe_menu_action.dart';
sealed class AIAction {
const AIAction();
String get label;
}
class PredefinedAction extends AIAction {
final AIScribeMenuAction action;
const PredefinedAction(this.action);
@override
String get label => action.fullLabel;
}
class CustomPromptAction extends AIAction {
final String prompt;
const CustomPromptAction(this.prompt);
@override
String get label => 'Help me write';
}
@@ -0,0 +1,124 @@
enum AIScribeMenuAction {
correctGrammar,
improveMakeShorter,
improveExpandContext,
improveEmojify,
improveTransformToBullets,
changeToneProfessional,
changeToneCasual,
changeTonePolite,
translateFrench,
translateEnglish,
translateRussian,
translateVietnamese;
String get label {
switch (this) {
case AIScribeMenuAction.correctGrammar:
return 'Correct grammar';
case AIScribeMenuAction.improveMakeShorter:
return 'Make it shorter';
case AIScribeMenuAction.improveExpandContext:
return 'Expand context';
case AIScribeMenuAction.improveEmojify:
return 'Emojify';
case AIScribeMenuAction.improveTransformToBullets:
return 'Transform to bullets';
case AIScribeMenuAction.changeToneProfessional:
return 'More professional';
case AIScribeMenuAction.changeToneCasual:
return 'More casual';
case AIScribeMenuAction.changeTonePolite:
return 'More polite';
case AIScribeMenuAction.translateFrench:
return 'French';
case AIScribeMenuAction.translateEnglish:
return 'English';
case AIScribeMenuAction.translateRussian:
return 'Russian';
case AIScribeMenuAction.translateVietnamese:
return 'Vietnamese';
}
}
AIScribeMenuCategory get category {
switch (this) {
case AIScribeMenuAction.correctGrammar:
return AIScribeMenuCategory.correctGrammar;
case AIScribeMenuAction.improveMakeShorter:
case AIScribeMenuAction.improveExpandContext:
case AIScribeMenuAction.improveEmojify:
case AIScribeMenuAction.improveTransformToBullets:
return AIScribeMenuCategory.improve;
case AIScribeMenuAction.changeToneProfessional:
case AIScribeMenuAction.changeToneCasual:
case AIScribeMenuAction.changeTonePolite:
return AIScribeMenuCategory.changeTone;
case AIScribeMenuAction.translateFrench:
case AIScribeMenuAction.translateEnglish:
case AIScribeMenuAction.translateRussian:
case AIScribeMenuAction.translateVietnamese:
return AIScribeMenuCategory.translate;
}
}
String get fullLabel {
final categoryLabel = category.label;
if (category.hasSubmenu) {
return '$categoryLabel > $label';
} else {
return label;
}
}
}
enum AIScribeMenuCategory {
correctGrammar,
improve,
changeTone,
translate;
String get label {
switch (this) {
case AIScribeMenuCategory.correctGrammar:
return 'Correct grammar';
case AIScribeMenuCategory.improve:
return 'Improve';
case AIScribeMenuCategory.changeTone:
return 'Change tone';
case AIScribeMenuCategory.translate:
return 'Translate';
}
}
List<AIScribeMenuAction> get actions {
switch (this) {
case AIScribeMenuCategory.correctGrammar:
return [AIScribeMenuAction.correctGrammar];
case AIScribeMenuCategory.improve:
return [
AIScribeMenuAction.improveMakeShorter,
AIScribeMenuAction.improveExpandContext,
AIScribeMenuAction.improveEmojify,
AIScribeMenuAction.improveTransformToBullets,
];
case AIScribeMenuCategory.changeTone:
return [
AIScribeMenuAction.changeToneProfessional,
AIScribeMenuAction.changeToneCasual,
AIScribeMenuAction.changeTonePolite,
];
case AIScribeMenuCategory.translate:
return [
AIScribeMenuAction.translateFrench,
AIScribeMenuAction.translateEnglish,
AIScribeMenuAction.translateRussian,
AIScribeMenuAction.translateVietnamese,
];
}
}
bool get hasSubmenu {
return actions.length > 1;
}
}