diff --git a/lib/bloc/eeg_state.dart b/lib/bloc/eeg_state.dart index ccf6895..751979a 100644 --- a/lib/bloc/eeg_state.dart +++ b/lib/bloc/eeg_state.dart @@ -1,5 +1,6 @@ import 'dart:async'; - import 'package:http/http.dart' as http; +import 'package:gemini_app/config.dart'; +import 'package:http/http.dart' as http; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -11,13 +12,19 @@ class EegState { required this.mind_wandering, required this.focus, }); + + String getJsonString() { + return '{"mind_wandering": $mind_wandering, "focus": $focus}'; + } } class EegCubit extends Cubit { - EegCubit() : super(EegState(mind_wandering: 0.0, focus: 0.0)) { + EegCubit() : super(EegState(mind_wandering: 0.9, focus: 0.1)) { // Start the timer when the cubit is created - startPolling(); + if (isDebug) { + startPolling(); + } } Timer? _timer; @@ -43,6 +50,10 @@ class EegCubit extends Cubit { Future> fetchEegData() async { + if (isDebug) { + return [0.9, 0.1]; // Placeholder ret + } + final url = Uri.parse('http://192.168.83.153:1234'); try { @@ -83,4 +94,13 @@ Future> fetchEegData() async { stopPolling(); return super.close(); } + + void toggleState() { + // Toggle the state between mind_wandering and focus + if (state.mind_wandering > state.focus) { + updateEegData(state.focus, state.mind_wandering); + } else { + updateEegData(state.mind_wandering, state.focus); + } + } } diff --git a/lib/bloc/gemini_state.dart b/lib/bloc/gemini_state.dart index 56748c4..36fa7cd 100644 --- a/lib/bloc/gemini_state.dart +++ b/lib/bloc/gemini_state.dart @@ -1,5 +1,7 @@ import 'package:bloc/bloc.dart'; import 'package:flutter/services.dart'; +import 'package:gemini_app/config.dart'; +import 'package:gemini_app/bloc/eeg_state.dart'; import 'package:google_generative_ai/google_generative_ai.dart'; enum GeminiStatus { initial, loading, success, error } @@ -40,7 +42,7 @@ class GeminiState { class GeminiCubit extends Cubit { GeminiCubit() : super(GeminiState.initialState); -void sendMessage(String prompt) async { +void sendMessage(String prompt, EegState eegState) async { var messagesWithoutPrompt = state.messages; var messagesWithPrompt = state.messages + [ Content.text(prompt) @@ -59,20 +61,23 @@ void sendMessage(String prompt) async { 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. -Write the response in two parts: -State analysis: -Tutor response: """; + Use language: POLISH +Write the response in markdown and split it into two parts: +State analysis: describe what is the state of the student and how to best approach them +Tutor response: continue with the lesson, respond to answers, etc"""; final model = GenerativeModel( model: 'gemini-1.5-pro-latest', - apiKey: '', + apiKey: geminiApiKey, safetySettings: safetySettings, systemInstruction: Content.system(systemPrmpt) ); try { final chat = model.startChat(history: messagesWithoutPrompt); - final stream = chat.sendMessageStream(Content.text(prompt)); + final stream = chat.sendMessageStream( + Content.text("EEG DATA:\n${eegState.getJsonString()}\nPytanie:\n$prompt") + ); String responseText = ''; @@ -92,4 +97,8 @@ Tutor response: """; )); } } + + void resetConversation() { + emit(GeminiState.initialState); + } } \ No newline at end of file diff --git a/lib/config.dart b/lib/config.dart new file mode 100644 index 0000000..f1b065f --- /dev/null +++ b/lib/config.dart @@ -0,0 +1,2 @@ +const String geminiApiKey = ''; +const bool isDebug = true; \ No newline at end of file diff --git a/lib/screens/gemini_chat_screen.dart b/lib/screens/gemini_chat_screen.dart index 21e0333..8f3bbed 100644 --- a/lib/screens/gemini_chat_screen.dart +++ b/lib/screens/gemini_chat_screen.dart @@ -35,7 +35,6 @@ class GeminiChatState extends State { void initState() { super.initState(); _startConversation(); - context.read().startPolling(); } @override @@ -47,17 +46,26 @@ void dispose() { void _startConversation() async { final String rjp = await rootBundle.loadString('assets/lessons/rjp.md'); print(rjp); - context.read().sendMessage("Zacznij prowadzić lekcje na podstawie poniszego skryptu:\n" + rjp); + context.read().sendMessage("Jesteś nauczycielem/chatbotem prowadzącym zajęcia z jednym uczniem. Uczeń ma możliwość zadawania pytań w trakcie, natomiast jesteś odpowiedzialny za prowadzenie lekcji i przedstawienie tematu. Zacznij prowadzić lekcje dla jednego ucznia na podstawie poniszego skryptu:\n" + rjp, context.read().state); } void _sendMessage() async { - context.read().sendMessage(_textController.text); + context.read().sendMessage(_textController.text, context.read().state); _textController.clear(); } + void _toggleEegState() { + context.read().toggleState(); + } + + void _resetConversation() { + context.read().resetConversation(); + _startConversation(); + } @override Widget build(BuildContext context) { return Scaffold( + resizeToAvoidBottomInset: true, appBar: AppBar( title: const Text('Gemini Pro Chat'), ), @@ -103,10 +111,26 @@ void dispose() { ), onSubmitted: (_) => _sendMessage(), ), - ElevatedButton( - onPressed: _sendMessage, - child: const Text('Send'), - ), + Row( + children: [ + Expanded( + child: ElevatedButton( + onPressed: _sendMessage, + child: const Text('Send'), + ), + ), + const SizedBox(width: 8), + ElevatedButton( + onPressed: _resetConversation, + child: const Text('Reset'), + ), + const SizedBox(width: 8), + ElevatedButton( + onPressed: _toggleEegState, + child: const Text('Toggle State'), + ), + ], + ), ], ), ),