Code fixes, style, analysis separation
This commit is contained in:
parent
ff9cdc02d8
commit
ebededacc1
1
lib/api_key.dart
Normal file
1
lib/api_key.dart
Normal file
@ -0,0 +1 @@
|
|||||||
|
const String geminiApiKey = '';
|
@ -0,0 +1 @@
|
|||||||
|
|
@ -2,8 +2,8 @@ import 'dart:convert';
|
|||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:gemini_app/api_key.dart';
|
||||||
import 'package:gemini_app/config.dart';
|
import 'package:gemini_app/config.dart';
|
||||||
import 'package:gemini_app/bloc/eeg_state.dart';
|
|
||||||
import 'package:gemini_app/eeg/eeg_service.dart';
|
import 'package:gemini_app/eeg/eeg_service.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:google_generative_ai/google_generative_ai.dart';
|
import 'package:google_generative_ai/google_generative_ai.dart';
|
||||||
@ -23,6 +23,10 @@ here describe what is the state of the student and how to best approach them
|
|||||||
here continue with the lesson, respond to answers, etc
|
here continue with the lesson, respond to answers, etc
|
||||||
""";
|
""";
|
||||||
|
|
||||||
|
const String LESSON_START_TOKEN = "<LESSON_START_TOKEN>";
|
||||||
|
const String ANALYSIS_START_TOKEN = "<ANALYSIS_START_TOKEN>";
|
||||||
|
const String QUIZ_START_TOKEN = "<QUIZ_START_TOKEN>";
|
||||||
|
|
||||||
enum GeminiStatus { initial, loading, success, error }
|
enum GeminiStatus { initial, loading, success, error }
|
||||||
|
|
||||||
// enum MessageType { text, image, audio, video }
|
// enum MessageType { text, image, audio, video }
|
||||||
@ -147,7 +151,8 @@ class GeminiCubit extends Cubit<GeminiState> {
|
|||||||
|
|
||||||
void startLesson() async {
|
void startLesson() async {
|
||||||
final quizQuestions = await loadQuizQuestions();
|
final quizQuestions = await loadQuizQuestions();
|
||||||
final String lessonScript = await rootBundle.loadString('assets/lessons/cells.md');
|
final String lessonScript =
|
||||||
|
await rootBundle.loadString('assets/lessons/cells.md');
|
||||||
// final String prompt =
|
// final String prompt =
|
||||||
// "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";
|
// "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";
|
||||||
final String prompt =
|
final String prompt =
|
||||||
@ -181,42 +186,51 @@ class GeminiCubit extends Cubit<GeminiState> {
|
|||||||
model: model);
|
model: model);
|
||||||
emit(initialState);
|
emit(initialState);
|
||||||
|
|
||||||
try {
|
sendMessage("");
|
||||||
final chat = state.model!.startChat(history: [Content.text(prompt)]);
|
|
||||||
final stream = chat.sendMessageStream(Content.text(
|
|
||||||
"EEG DATA:\n${GetIt.instance<EegService>().state.getJsonString()}\nMessage:\n$prompt"));
|
|
||||||
|
|
||||||
String responseText = '';
|
// try {
|
||||||
|
// final chat = state.model!.startChat(history: [Content.text(prompt)]);
|
||||||
|
// final stream = chat.sendMessageStream(Content.text(
|
||||||
|
// "EEG DATA:\n${GetIt.instance<EegService>().state.getJsonString()}\nMessage:\n$prompt"));
|
||||||
|
|
||||||
await for (final chunk in stream) {
|
// String responseText = '';
|
||||||
responseText += chunk.text ?? '';
|
|
||||||
emit(initialState.copyWith(
|
// await for (final chunk in stream) {
|
||||||
status: GeminiStatus.success,
|
// responseText += chunk.text ?? '';
|
||||||
messages: [
|
// emit(initialState.copyWith(
|
||||||
lessonScriptMessage,
|
// status: GeminiStatus.success,
|
||||||
Message(
|
// messages: [
|
||||||
source: MessageSource.agent,
|
// lessonScriptMessage,
|
||||||
text: responseText,
|
// Message(
|
||||||
type: MessageType.text)
|
// source: MessageSource.agent,
|
||||||
],
|
// text: responseText,
|
||||||
model: model));
|
// type: MessageType.text)
|
||||||
}
|
// ],
|
||||||
} catch (e) {
|
// model: model));
|
||||||
emit(GeminiState(
|
// }
|
||||||
status: GeminiStatus.error,
|
// } catch (e) {
|
||||||
messages: state.messages,
|
// emit(GeminiState(
|
||||||
error: e.toString(),
|
// status: GeminiStatus.error,
|
||||||
));
|
// messages: state.messages,
|
||||||
}
|
// error: e.toString(),
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendMessage(String prompt) async {
|
void sendMessage(String prompt) async {
|
||||||
List<Message> messagesWithoutPrompt = state.messages;
|
List<Message> messagesWithoutPrompt = state.messages;
|
||||||
var messagesWithPrompt = state.messages +
|
List<Message> messagesWithPrompt;
|
||||||
|
if (prompt == "") {
|
||||||
|
messagesWithPrompt = state.messages;
|
||||||
|
} else {
|
||||||
|
messagesWithPrompt = state.messages +
|
||||||
[
|
[
|
||||||
Message(
|
Message(
|
||||||
text: prompt, type: MessageType.text, source: MessageSource.user)
|
text: prompt,
|
||||||
|
type: MessageType.text,
|
||||||
|
source: MessageSource.user)
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
status: GeminiStatus.loading,
|
status: GeminiStatus.loading,
|
||||||
@ -233,8 +247,20 @@ class GeminiCubit extends Cubit<GeminiState> {
|
|||||||
|
|
||||||
String responseText = '';
|
String responseText = '';
|
||||||
|
|
||||||
|
bool isAnalysisDone = false;
|
||||||
|
|
||||||
await for (final chunk in stream) {
|
await for (final chunk in stream) {
|
||||||
responseText += chunk.text ?? '';
|
responseText += chunk.text ?? '';
|
||||||
|
if (responseText.contains(LESSON_START_TOKEN)) {
|
||||||
|
isAnalysisDone = true;
|
||||||
|
var startIndex = responseText.indexOf(LESSON_START_TOKEN) +
|
||||||
|
LESSON_START_TOKEN.length;
|
||||||
|
var analysisData = responseText.substring(0, startIndex);
|
||||||
|
print("ANALYSIS DATA: $analysisData");
|
||||||
|
responseText =
|
||||||
|
responseText.substring(startIndex, responseText.length);
|
||||||
|
}
|
||||||
|
if (isAnalysisDone) {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
status: GeminiStatus.success,
|
status: GeminiStatus.success,
|
||||||
messages: messagesWithPrompt +
|
messages: messagesWithPrompt +
|
||||||
@ -245,6 +271,7 @@ class GeminiCubit extends Cubit<GeminiState> {
|
|||||||
type: MessageType.text)
|
type: MessageType.text)
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (responseText.contains("<QUIZ_START_TOKEN>")) {
|
if (responseText.contains("<QUIZ_START_TOKEN>")) {
|
||||||
enterQuizMode();
|
enterQuizMode();
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
const String geminiApiKey = '';
|
const String geminiApiKey = 'AIzaSyBU-vIDA4IUfRReXcu7Vdw53gnrnroJjzI';
|
||||||
const bool isDebug = true;
|
const bool isDebug = true;
|
||||||
|
@ -2,26 +2,24 @@ import 'dart:async';
|
|||||||
import 'package:gemini_app/config.dart';
|
import 'package:gemini_app/config.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
||||||
|
|
||||||
class EegState {
|
class EegState {
|
||||||
final double mind_wandering;
|
final double mindWandering;
|
||||||
final double focus;
|
final double focus;
|
||||||
|
|
||||||
EegState({
|
EegState({
|
||||||
required this.mind_wandering,
|
required this.mindWandering,
|
||||||
required this.focus,
|
required this.focus,
|
||||||
});
|
});
|
||||||
|
|
||||||
String getJsonString() {
|
String getJsonString() {
|
||||||
return '{"mind_wandering": $mind_wandering, "focus": $focus}';
|
return '{"mind_wandering": $mindWandering, "focus": $focus}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EegService {
|
class EegService {
|
||||||
EegState state;
|
EegState state;
|
||||||
|
|
||||||
EegService() : state = EegState(mind_wandering: 0.9, focus: 0.1) {
|
EegService() : state = EegState(mindWandering: 0.9, focus: 0.1) {
|
||||||
// Start the timer when the cubit is created
|
// Start the timer when the cubit is created
|
||||||
if (!isDebug) {
|
if (!isDebug) {
|
||||||
startPolling();
|
startPolling();
|
||||||
@ -32,7 +30,7 @@ class EegService {
|
|||||||
|
|
||||||
void startPolling() {
|
void startPolling() {
|
||||||
// Poll every 1 second (adjust the duration as needed)
|
// Poll every 1 second (adjust the duration as needed)
|
||||||
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
|
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||||
// Simulate getting new EEG data
|
// Simulate getting new EEG data
|
||||||
// In a real application, you would fetch this data from your EEG device or API
|
// In a real application, you would fetch this data from your EEG device or API
|
||||||
// double newMindWandering = (DateTime.now().millisecondsSinceEpoch % 100) / 100;
|
// double newMindWandering = (DateTime.now().millisecondsSinceEpoch % 100) / 100;
|
||||||
@ -84,16 +82,16 @@ class EegService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateEegData(double mindWandering, double focus) {
|
void updateEegData(double mindWandering, double focus) {
|
||||||
state = EegState(mind_wandering: mindWandering, focus: focus);
|
state = EegState(mindWandering: mindWandering, focus: focus);
|
||||||
print('Mind Wandering: $mindWandering, Focus: $focus');
|
print('Mind Wandering: $mindWandering, Focus: $focus');
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleState() {
|
void toggleState() {
|
||||||
// Toggle the state between mind_wandering and focus
|
// Toggle the state between mind_wandering and focus
|
||||||
if (state.mind_wandering > state.focus) {
|
if (state.mindWandering > state.focus) {
|
||||||
updateEegData(state.focus, state.mind_wandering);
|
updateEegData(state.focus, state.mindWandering);
|
||||||
} else {
|
} else {
|
||||||
updateEegData(state.mind_wandering, state.focus);
|
updateEegData(state.mindWandering, state.focus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,14 +58,14 @@ class GeminiChatState extends State<GeminiChat> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _sendMessage() async {
|
void _sendMessage() async {
|
||||||
context
|
context.read<GeminiCubit>().sendMessage(_textController.text);
|
||||||
.read<GeminiCubit>()
|
|
||||||
.sendMessage(_textController.text);
|
|
||||||
_textController.clear();
|
_textController.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _toggleEegState() {
|
void _toggleEegState() {
|
||||||
|
setState(() {
|
||||||
_eegService.toggleState();
|
_eegService.toggleState();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _resetConversation() {
|
void _resetConversation() {
|
||||||
@ -91,20 +91,23 @@ class GeminiChatState extends State<GeminiChat> {
|
|||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Card(
|
Card(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Mind Wandering: ${_eegService.state.mind_wandering.toStringAsFixed(2)}'),
|
'Mind Wandering: ${_eegService.state.mindWandering.toStringAsFixed(2)}'),
|
||||||
Text('Focus: ${_eegService.state.focus.toStringAsFixed(2)}'),
|
Text(
|
||||||
|
'Focus: ${_eegService.state.focus.toStringAsFixed(2)}'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BlocBuilder<GeminiCubit, GeminiState>(
|
child: BlocBuilder<GeminiCubit, GeminiState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
@ -118,54 +121,87 @@ class GeminiChatState extends State<GeminiChat> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
BlocBuilder<GeminiCubit, GeminiState>(
|
BlocBuilder<GeminiCubit, GeminiState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return state.isQuizMode
|
return state.isQuizMode
|
||||||
? Container() // Hide text input in quiz mode
|
? Container()
|
||||||
: TextField(
|
: TextField(
|
||||||
controller: _textController,
|
controller: _textController,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: 'Enter your message',
|
hintText: 'Enter your message',
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
fillColor: Colors.grey[200],
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 16.0, vertical: 12.0),
|
||||||
),
|
),
|
||||||
onSubmitted: (_) => _sendMessage(),
|
onSubmitted: (_) => _sendMessage(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
BlocBuilder<GeminiCubit, GeminiState>(
|
// BlocBuilder<GeminiCubit, GeminiState>(
|
||||||
builder: (context, state) {
|
// builder: (context, state) {
|
||||||
return state.isQuizMode
|
// return state.isQuizMode
|
||||||
? Container()
|
// ? Container()
|
||||||
: Expanded(
|
// : Expanded(
|
||||||
child: ElevatedButton(
|
// child: ElevatedButton(
|
||||||
|
// onPressed: _sendMessage,
|
||||||
|
// child: const Text('Send'),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
ElevatedButton(
|
||||||
onPressed: _sendMessage,
|
onPressed: _sendMessage,
|
||||||
child: const Text('Send'),
|
child: const Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.send),
|
||||||
|
SizedBox(width: 3),
|
||||||
|
Text('Send'),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: _resetConversation,
|
onPressed: _resetConversation,
|
||||||
child: const Text('Reset'),
|
child: const Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.refresh),
|
||||||
|
SizedBox(width: 3),
|
||||||
|
Text('Reset'),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: _toggleEegState,
|
onPressed: _toggleEegState,
|
||||||
child: const Text('Toggle State'),
|
child: const Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.toggle_on),
|
||||||
|
SizedBox(width: 3),
|
||||||
|
Text('Toggle State'),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
|
||||||
BlocBuilder<GeminiCubit, GeminiState>(
|
|
||||||
builder: (context, state) {
|
|
||||||
return state.isQuizMode
|
|
||||||
? Container()
|
|
||||||
: ElevatedButton(
|
|
||||||
onPressed: _enterQuizMode,
|
|
||||||
child: const Text('Start Quiz'),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
|
// ElevatedButton(
|
||||||
|
// onPressed: _enterQuizMode,
|
||||||
|
// child: const Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
// children: [
|
||||||
|
// Icon(Icons.quiz),
|
||||||
|
// SizedBox(width: 8),
|
||||||
|
// Text('Start Quiz'),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -302,12 +338,13 @@ class BouncingDotsState extends State<BouncingDots>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: List.generate(3, (index) {
|
children: List.generate(3, (index) {
|
||||||
return AnimatedBuilder(
|
return AnimatedBuilder(
|
||||||
animation: _controllers[index],
|
animation: _controllers[index],
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
return Container(
|
return Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
padding: const EdgeInsets.all(2.5),
|
padding: const EdgeInsets.all(2.5),
|
||||||
child: Transform.translate(
|
child: Transform.translate(
|
||||||
offset: Offset(0, _animations[index].value),
|
offset: Offset(0, _animations[index].value),
|
||||||
|
@ -18,7 +18,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.11.0"
|
version: "2.11.0"
|
||||||
bloc:
|
bloc:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: bloc
|
name: bloc
|
||||||
sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
|
sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
|
||||||
@ -124,13 +124,13 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.3"
|
version: "0.4.3"
|
||||||
http:
|
http:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: http
|
name: http
|
||||||
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
|
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.2.2"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -42,6 +42,8 @@ dependencies:
|
|||||||
flutter_markdown: ^0.7.3
|
flutter_markdown: ^0.7.3
|
||||||
flutter_bloc: ^8.0.1
|
flutter_bloc: ^8.0.1
|
||||||
get_it: ^7.7.0
|
get_it: ^7.7.0
|
||||||
|
http: ^1.2.2
|
||||||
|
bloc: ^8.1.4
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user