Quiz fixes

This commit is contained in:
Dawid Pietrykowski 2024-08-08 19:25:46 +02:00
parent b8e87d15d2
commit b04585e2e2
3 changed files with 65 additions and 14 deletions

View File

@ -11,11 +11,12 @@ const String systemPrmpt =
"""You are an AI tutor helping students understand topics with help of biometric data. You will be supplied with a json containing data extracted from an EEG device, use that data to modify your approach and help the student learn more effectively. """You are an AI tutor helping students understand topics with help of biometric data. You will be supplied with a json containing data extracted from an EEG device, use that data to modify your approach and help the student learn more effectively.
At the start you will be provided a script with a lesson to cover. At the start you will be provided a script with a lesson to cover.
Keep the analysis and responses short. Keep the analysis and responses short.
Student is 15 years old.
After completing the theoretical part there's a quiz, you can start it yourself at the appropriate time or react to users' request by including <QUIZ_START_TOKEN> at the start of your response After completing the theoretical part there's a quiz, you can start it yourself at the appropriate time or react to users' request by including <QUIZ_START_TOKEN> at the start of your response
Write the response in markdown and split it into two parts (include the tokens): Write the response in markdown and split it into two parts (include the tokens):
optional: <QUIZ_START_TOKEN> optional: <QUIZ_START_TOKEN> (makes the app transition to quiz mode, do not write the question yourself, use it ONLY when you want to start the quiz)
<ANALYSIS_START_TOKEN> <ANALYSIS_START_TOKEN>
here describe what is the state of the student and how to best approach them here describe what is the state of the student and how to best approach them
<LESSON_START_TOKEN> <LESSON_START_TOKEN>
@ -30,7 +31,7 @@ enum GeminiStatus { initial, loading, success, error }
// enum MessageType { text, image, audio, video } // enum MessageType { text, image, audio, video }
enum MessageSource { user, agent } enum MessageSource { user, agent, app}
class QuizMessage { class QuizMessage {
final String content; final String content;
@ -80,10 +81,33 @@ class Message {
} }
Content toGeminiContent() { Content toGeminiContent() {
if (source == MessageSource.user || type == MessageType.lessonScript) { // if (source == MessageSource.user || type == MessageType.lessonScript) {
return Content.text(text); // return Content.text(text);
} else { // } else {
return Content.model([TextPart(text)]); // return Content.model([TextPart(text)]);
// }
switch (type) {
case MessageType.text:
if (source == MessageSource.user) {
return Content.text(text);
} else {
return Content.model([TextPart(text)]);
}
case MessageType.lessonScript:
return Content.text(text);
case MessageType.quizQuestion:
String question = text;
List<String> options = quizOptions!.map((option) => option.trim()).toList();
String answer = options[correctAnswer!];
String formattedQuestion = "$question\n\nOptions:\n${options.map((option) => "- $option").join('\n')}\n\nCorrect Answer: $answer";
return Content.model([TextPart(formattedQuestion)]);
case MessageType.quizAnswer:
String expectedAnswer = quizOptions![correctAnswer!];
bool userCorrect = expectedAnswer == text;
String result = userCorrect ? "User answered correctly with: $text" : "User answered incorrectly with: $text instead of $expectedAnswer";
return Content.text(result);
default:
throw UnsupportedError('Unsupported message type');
} }
} }
} }
@ -237,16 +261,18 @@ class GeminiCubit extends Cubit<GeminiState> {
)); ));
try { try {
final chat = state.model!.startChat( final chatHistory = messagesWithoutPrompt
history: messagesWithoutPrompt
.map((mess) => mess.toGeminiContent()) .map((mess) => mess.toGeminiContent())
.toList()); .toList();
final chat = state.model!.startChat(
history: chatHistory);
final stream = chat.sendMessageStream(Content.text( final stream = chat.sendMessageStream(Content.text(
"EEG DATA:\n${GetIt.instance<EegService>().state.getJsonString()}\nUser message:\n$prompt")); "EEG DATA:\n${GetIt.instance<EegService>().state.getJsonString()}\nUser message:\n$prompt"));
String responseText = ''; String responseText = '';
bool isAnalysisDone = false; bool isAnalysisDone = false;
String analysisData = "";
await for (final chunk in stream) { await for (final chunk in stream) {
responseText += chunk.text ?? ''; responseText += chunk.text ?? '';
@ -254,7 +280,7 @@ class GeminiCubit extends Cubit<GeminiState> {
isAnalysisDone = true; isAnalysisDone = true;
var startIndex = responseText.indexOf(LESSON_START_TOKEN) + var startIndex = responseText.indexOf(LESSON_START_TOKEN) +
LESSON_START_TOKEN.length; LESSON_START_TOKEN.length;
var analysisData = responseText.substring(0, startIndex); analysisData = responseText.substring(0, startIndex);
print("ANALYSIS DATA: $analysisData"); print("ANALYSIS DATA: $analysisData");
responseText = responseText =
responseText.substring(startIndex, responseText.length); responseText.substring(startIndex, responseText.length);
@ -272,7 +298,10 @@ class GeminiCubit extends Cubit<GeminiState> {
} }
} }
if (responseText.contains("<QUIZ_START_TOKEN>")) { if (responseText.contains(QUIZ_START_TOKEN) || analysisData.contains(QUIZ_START_TOKEN)) {
emit(state.copyWith(
status: GeminiStatus.success,
messages: messagesWithPrompt));
enterQuizMode(); enterQuizMode();
} }
} catch (e) { } catch (e) {
@ -326,6 +355,27 @@ class GeminiCubit extends Cubit<GeminiState> {
void askNextQuizQuestion() { void askNextQuizQuestion() {
var currentQuizIndex = state.currentQuizIndex + 1; var currentQuizIndex = state.currentQuizIndex + 1;
if (currentQuizIndex >= state.quizQuestions!.length) {
// if (currentQuizIndex >= 2) {
List<Message> messagesWithPrompt = state.messages +
[
Message(
text: "Quiz is over. Write a summary of user's performance.",
type: MessageType.text,
source: MessageSource.app)
];
// Quiz is over
emit(state.copyWith(isQuizMode: false, currentQuizIndex: 0,
messages: messagesWithPrompt));
// Send a message to Gemini to end the quiz
sendMessage("");
return;
}
final quizQuestion = state.quizQuestions![currentQuizIndex]; final quizQuestion = state.quizQuestions![currentQuizIndex];
final quizQuestionMessage = Message( final quizQuestionMessage = Message(
@ -348,6 +398,7 @@ class GeminiCubit extends Cubit<GeminiState> {
} }
void checkAnswer(int answerIndex) { void checkAnswer(int answerIndex) {
print("checkAnswer $answerIndex");
passAnswerToGemini(answerIndex); passAnswerToGemini(answerIndex);
} }

View File

@ -1,2 +1 @@
const String geminiApiKey = 'AIzaSyBU-vIDA4IUfRReXcu7Vdw53gnrnroJjzI';
const bool isDebug = true; const bool isDebug = true;

View File

@ -226,7 +226,8 @@ class GeminiChatState extends State<GeminiChat> {
); );
} }
if (state.messages[index].type == MessageType.lessonScript) { if (state.messages[index].type == MessageType.lessonScript ||
state.messages[index].source == MessageSource.app) {
// skip // skip
return Container(); return Container();
} }
@ -254,7 +255,7 @@ class GeminiChatState extends State<GeminiChat> {
), ),
); );
} else if (message.type == MessageType.quizAnswer) { } else if (message.type == MessageType.quizAnswer) {
bool correct = message.text == message.correctAnswer; bool correct = message.text == message.quizOptions![message.correctAnswer!];
var text = Text( var text = Text(
correct correct
? "Correct!" ? "Correct!"