diff --git a/Frontend/lib/mih_packages/mzansi_ai/ai_chat.dart b/Frontend/lib/mih_packages/mzansi_ai/ai_chat.dart index 4a5cdfd6..29e83f14 100644 --- a/Frontend/lib/mih_packages/mzansi_ai/ai_chat.dart +++ b/Frontend/lib/mih_packages/mzansi_ai/ai_chat.dart @@ -1,10 +1,7 @@ -import 'dart:async'; import 'dart:convert'; import 'package:Mzansi_Innovation_Hub/main.dart'; -import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_dropdown_input.dart'; -import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_text_input.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih-app_tool_body.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih_app_window.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; @@ -29,20 +26,17 @@ class AiChat extends StatefulWidget { } class _AiChatState extends State { - final TextEditingController _modelCopntroller = TextEditingController(); - final TextEditingController _fontSizeCopntroller = TextEditingController(); + TextEditingController _modelCopntroller = TextEditingController(); final ValueNotifier _showModelOptions = ValueNotifier(false); List _messages = []; late types.User _user; late types.User _mihAI; String systemPromt = "You are a helpful and friendly AI assistant. You are running on a system called MIH which was created by \"Mzansi Innovation Hub\" a South African based company."; - bool _aiThinking = false; final client = ollama.OllamaClient( baseUrl: "${AppEnviroment.baseAiUrl}/api", ); List _chatHistory = []; - double _chatFrontSize = 17; void _addMessage(types.Message message) { setState(() { @@ -73,66 +67,86 @@ class _AiChatState extends State { } void _handleMessageBack(String userMessage) async { + // types.TextMessage textMessage; + // String aiResponse = ""; + // final aiResponseStream = showDialog( context: context, builder: (context) { return const Mihloadingcircle(); }, ); - Stream aiChatStream = - _generateChatCompletionWithHistoryStream(userMessage, client); - + _generateChatCompletionWithHistoryStream(userMessage, client) + .listen((response) { + //aiResponse = response; //.split("").last.trim(); + }); Navigator.of(context).pop(); showDialog( context: context, - barrierDismissible: false, builder: (context) { - return responseWindow(aiChatStream); + return responseWindow(); }, ); + // setState(() { + // _chatHistory.add( + // ollama.Message( + // role: ollama.MessageRole.assistant, + // content: aiResponse, + // ), + // ); + // }); + // textMessage = types.TextMessage( + // author: _mihAI, + // createdAt: DateTime.now().millisecondsSinceEpoch, + // id: const Uuid().v4(), + // text: aiResponse //message.text, + // ); + + // _addMessage(textMessage); + // print(_chatHistory.toString()); + // Navigator.of(context).pop(); } - Widget responseWindow( - Stream aiChatStream, - // StreamSubscription aiChatSubscription, - ) { - StreamSubscription aiChatSubscription = - aiChatStream.listen((response) {}); + Widget responseWindow() { types.TextMessage textMessage; return StreamBuilder( - stream: _generateChatCompletionWithHistoryStream("", client), + stream: _generateChatCompletionWithHistoryStream("Hello", client), builder: (context, snapshot) { if (snapshot.hasData) { return MihAppWindow( fullscreen: false, windowTitle: 'Mzansi AI Thoughts', - windowTools: const [], - onWindowTapClose: () { - if (_aiThinking) { - aiChatSubscription.cancel(); - } - setState(() { - _chatHistory.add( - ollama.Message( - role: ollama.MessageRole.assistant, - content: snapshot.requireData, - ), - ); - }); - textMessage = types.TextMessage( - author: _mihAI, - createdAt: DateTime.now().millisecondsSinceEpoch, - id: const Uuid().v4(), - // metadata: { - // "thoughts": snapshot.requireData - // }, - text: snapshot.requireData - .replaceAll("\n\n", "Thinking:\n") - .replaceAll("\n", "Thinking:\n") - .replaceAll("\n\n", "Answer:\n"), //message.text, - ); + windowTools: [ + IconButton( + onPressed: () { + setState(() { + _chatHistory.add( + ollama.Message( + role: ollama.MessageRole.assistant, + content: snapshot.requireData, + ), + ); + }); + textMessage = types.TextMessage( + author: _mihAI, + createdAt: DateTime.now().millisecondsSinceEpoch, + id: const Uuid().v4(), + // metadata: { + // "thoughts": snapshot.requireData + // }, + text: snapshot.requireData + .replaceAll("\n\n", "Thinking:\n") + .replaceAll( + "\n\n", "Answer:\n"), //message.text, + ); - _addMessage(textMessage); + _addMessage(textMessage); + Navigator.of(context).pop(); + }, + icon: const Icon(Icons.arrow_back), + ), + ], + onWindowTapClose: () { Navigator.of(context).pop(); }, windowBody: [ @@ -142,47 +156,10 @@ class _AiChatState extends State { style: TextStyle( color: MzanziInnovationHub.of(context)!.theme.secondaryColor(), - fontSize: _chatFrontSize, + fontSize: 12, fontWeight: FontWeight.bold, ), ), - const SizedBox(height: 15), - Visibility( - visible: _aiThinking == false, - child: MIHButton( - onTap: () { - setState(() { - _chatHistory.add( - ollama.Message( - role: ollama.MessageRole.assistant, - content: snapshot.requireData, - ), - ); - }); - textMessage = types.TextMessage( - author: _mihAI, - createdAt: DateTime.now().millisecondsSinceEpoch, - id: const Uuid().v4(), - // metadata: { - // "thoughts": snapshot.requireData - // }, - text: snapshot.requireData - .replaceAll("\n\n", "Thinking:\n") - .replaceAll("\n", "Thinking:\n") - .replaceAll( - "\n\n", "Answer:\n"), //message.text, - ); - - _addMessage(textMessage); - Navigator.of(context).pop(); - }, - buttonText: "Continue", - buttonColor: - MzanziInnovationHub.of(context)!.theme.successColor(), - textColor: - MzanziInnovationHub.of(context)!.theme.primaryColor(), - ), - ), ], ); } else { @@ -213,6 +190,19 @@ class _AiChatState extends State { }); } + // Future _generateChatCompletionWithHistory( + // String userMessage, + // final ollama.OllamaClient client, + // ) async { + // final generated = await client.generateChatCompletion( + // request: ollama.GenerateChatCompletionRequest( + // model: _modelCopntroller.text, + // messages: _chatHistory, + // ), + // ); + // return generated.message.content; + // } + Stream _generateChatCompletionWithHistoryStream( String userMessage, final ollama.OllamaClient client, @@ -224,16 +214,10 @@ class _AiChatState extends State { ), ); String text = ''; - setState(() { - _aiThinking = true; - }); await for (final res in aiStream) { text += (res.message.content); yield text; } - setState(() { - _aiThinking = false; - }); // print(text); } @@ -263,19 +247,19 @@ class _AiChatState extends State { errorColor: MzanziInnovationHub.of(context)!.theme.errorColor(), sentMessageBodyTextStyle: TextStyle( color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: _chatFrontSize, + fontSize: 17, fontWeight: FontWeight.w500, fontFamily: 'Segoe UI', ), receivedMessageBodyTextStyle: TextStyle( color: MzanziInnovationHub.of(context)!.theme.primaryColor(), - fontSize: _chatFrontSize, + fontSize: 17, fontWeight: FontWeight.w500, fontFamily: 'Segoe UI', ), emptyChatPlaceholderTextStyle: TextStyle( color: MzanziInnovationHub.of(context)!.theme.messageTextColor(), - fontSize: _chatFrontSize, + fontSize: 17, fontWeight: FontWeight.w500, fontFamily: 'Segoe UI', ), @@ -302,7 +286,6 @@ class _AiChatState extends State { id: const Uuid().v4(), ); _modelCopntroller.text = 'deepseek-r1:1.5b'; - _fontSizeCopntroller.text = _chatFrontSize.ceil().toString(); // _chatHistory.add( // ollama.Message( // role: ollama.MessageRole.system, @@ -317,54 +300,25 @@ class _AiChatState extends State { return MihAppToolBody( borderOn: false, bodyItem: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Expanded( - child: Container( - alignment: Alignment.centerLeft, - child: Row( - children: [ - Visibility( - visible: _showModelOptions.value == false, - child: IconButton( - onPressed: () { - if (_showModelOptions.value == true) { - setState(() { - _showModelOptions.value = false; - }); - } else { - setState(() { - _showModelOptions.value = true; - }); - } - }, - icon: const Icon(Icons.settings), - ), - ), - Visibility( - visible: _showModelOptions.value == true, - child: IconButton.filled( - onPressed: () { - if (_showModelOptions.value == true) { - setState(() { - _showModelOptions.value = false; - }); - } else { - setState(() { - _showModelOptions.value = true; - }); - } - }, - icon: const Icon(Icons.settings), - ), - ), - ], - ), - ), + IconButton( + onPressed: () { + if (_showModelOptions.value == true) { + setState(() { + _showModelOptions.value = false; + }); + } else { + setState(() { + _showModelOptions.value = true; + }); + } + }, + icon: const Icon(Icons.settings), ), Text( "Mzansi AI", @@ -376,16 +330,11 @@ class _AiChatState extends State { MzanziInnovationHub.of(context)!.theme.secondaryColor(), ), ), - Expanded( - child: Container( - alignment: Alignment.centerRight, - child: IconButton( - onPressed: () { - _resetChat(); - }, - icon: const Icon(Icons.refresh), - ), - ), + IconButton( + onPressed: () { + _resetChat(); + }, + icon: const Icon(Icons.refresh), ), ], ), @@ -394,83 +343,27 @@ class _AiChatState extends State { builder: (BuildContext context, bool value, Widget? child) { return Visibility( visible: value, - child: Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 25), - child: SizedBox( - width: 300, - child: MIHDropdownField( - controller: _modelCopntroller, - hintText: "AI Model", - dropdownOptions: const ['deepseek-r1:1.5b'], - required: true, - editable: true, - ), - ), - ) - ], - ), - ), - ); - }, - ), - const SizedBox(height: 15), - ValueListenableBuilder( - valueListenable: _showModelOptions, - builder: (BuildContext context, bool value, Widget? child) { - return Visibility( - visible: value, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 25), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - IconButton.filled( - onPressed: () { - setState(() { - _chatFrontSize -= 1; - _fontSizeCopntroller.text = - _chatFrontSize.ceil().toString(); - }); - }, - icon: const Icon( - Icons.remove, - ), - ), - const SizedBox(width: 10), - SizedBox( - width: 200, - child: MIHTextField( - controller: _fontSizeCopntroller, - hintText: "Chat Font Size", - editable: false, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 25), + child: SizedBox( + width: 300, + child: MIHDropdownField( + controller: _modelCopntroller, + hintText: "AI Model", + dropdownOptions: const ['deepseek-r1:1.5b'], required: true, + editable: true, ), ), - const SizedBox(width: 10), - IconButton.filled( - onPressed: () { - setState(() { - _chatFrontSize += 1; - _fontSizeCopntroller.text = - _chatFrontSize.ceil().toString(); - }); - }, - icon: const Icon( - Icons.add, - ), - ), - ], - ), + ) + ], ), ); }, ), - const SizedBox(height: 5), Expanded( child: Chat( messages: _messages,