From 1116894c52314fc3a79adb8d2d4dc7203209dac5 Mon Sep 17 00:00:00 2001 From: yaso Date: Fri, 24 Jan 2025 12:15:37 +0200 Subject: [PATCH] create chat body --- .../lib/mih_packages/mzansi_ai/ai_chat.dart | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 Frontend/lib/mih_packages/mzansi_ai/ai_chat.dart diff --git a/Frontend/lib/mih_packages/mzansi_ai/ai_chat.dart b/Frontend/lib/mih_packages/mzansi_ai/ai_chat.dart new file mode 100644 index 00000000..dbbddc28 --- /dev/null +++ b/Frontend/lib/mih_packages/mzansi_ai/ai_chat.dart @@ -0,0 +1,218 @@ +import 'dart:convert'; + +import 'package:Mzansi_Innovation_Hub/main.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_package/mih-app_tool_body.dart'; +import 'package:Mzansi_Innovation_Hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart'; +import 'package:Mzansi_Innovation_Hub/mih_env/env.dart'; +import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_chat_ui/flutter_chat_ui.dart'; +import 'package:flutter_chat_types/flutter_chat_types.dart' as types; +import 'package:flutter/services.dart' show rootBundle; +import 'package:ollama_dart/ollama_dart.dart' as ollama; +import 'package:uuid/uuid.dart'; + +class AiChat extends StatefulWidget { + final AppUser signedInUser; + const AiChat({ + super.key, + required this.signedInUser, + }); + + @override + State createState() => _AiChatState(); +} + +class _AiChatState extends State { + List _messages = []; + late types.User _user; + late types.User _mihAI; + final client = ollama.OllamaClient(baseUrl: "${AppEnviroment.baseAiUrl}/api"); + List _chatHistory = []; + + void _addMessage(types.Message message) { + setState(() { + _messages.insert(0, message); + }); + } + + void _handleSendPressed(types.PartialText message) { + final textMessage = types.TextMessage( + author: _user, + createdAt: DateTime.now().millisecondsSinceEpoch, + id: const Uuid().v4(), + text: message.text, + ); + //Add user prompt to history + setState(() { + _chatHistory.add( + ollama.Message( + role: ollama.MessageRole.user, + content: message.text, + ), + ); + }); + + _addMessage(textMessage); + + _handleMessageBack(message.text); + } + + void _handleMessageBack(String userMessage) async { + showDialog( + context: context, + builder: (context) { + return const Mihloadingcircle(); + }, + ); + types.TextMessage textMessage; + String aiResponse = ""; + await _generateChatCompletionWithHistory(userMessage, client) + .then((response) { + aiResponse = response.split("").last.trim(); + }); + 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(); + } + + void _loadMessages() async { + final response = await rootBundle.loadString('assets/messages.json'); + final messages = (jsonDecode(response) as List) + .map((e) => types.Message.fromJson(e as Map)) + .toList(); + + setState(() { + _messages = messages; + }); + } + + Future _generateChatCompletionWithHistory( + String userMessage, + final ollama.OllamaClient client, + ) async { + final generated = await client.generateChatCompletion( + request: ollama.GenerateChatCompletionRequest( + model: 'deepseek-r1:1.5b', + messages: _chatHistory, + ), + ); + return generated.message.content; + } + + ChatTheme getChatTheme() { + return DarkChatTheme( + backgroundColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + inputBackgroundColor: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + inputTextColor: MzanziInnovationHub.of(context)!.theme.primaryColor(), + inputTextCursorColor: + MzanziInnovationHub.of(context)!.theme.primaryColor(), + primaryColor: MzanziInnovationHub.of(context)!.theme.secondaryColor(), + secondaryColor: MzanziInnovationHub.of(context)!.theme.successColor(), + errorColor: MzanziInnovationHub.of(context)!.theme.errorColor(), + sentMessageBodyTextStyle: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 17, + fontWeight: FontWeight.w500, + fontFamily: 'Segoe UI', + ), + receivedMessageBodyTextStyle: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.primaryColor(), + fontSize: 17, + fontWeight: FontWeight.w500, + fontFamily: 'Segoe UI', + ), + emptyChatPlaceholderTextStyle: TextStyle( + color: MzanziInnovationHub.of(context)!.theme.messageTextColor(), + fontSize: 17, + fontWeight: FontWeight.w500, + fontFamily: 'Segoe UI', + ), + ); + } + + @override + void initState() { + super.initState(); + _user = types.User( + firstName: widget.signedInUser.fname, + id: widget.signedInUser.app_id, //'82091008-a484-4a89-ae75-a22bf8d6f3ac', + ); + _mihAI = types.User( + firstName: "Mzansi AI", + id: const Uuid().v4(), + ); + String systemPromt = + "You are a helpful and friendly AI assistant named 'Mzansi AI'(Please make sure you use the exact words 'Mzansi Ai' when asked whats your name or who you are.) who was created by 'Mzansi Innovation Hub'"; + _chatHistory.add( + ollama.Message( + role: ollama.MessageRole.system, + content: systemPromt, + ), + ); + _loadMessages(); + } + + @override + Widget build(BuildContext context) { + return MihAppToolBody( + borderOn: false, + bodyItem: Column( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Chat with Mzansi AI", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 25, + fontWeight: FontWeight.bold, + color: + MzanziInnovationHub.of(context)!.theme.secondaryColor(), + ), + ), + // IconButton( + // onPressed: () { + // _handleMessageBack(); + // }, + // icon: Icon(Icons.add), + // ), + ], + ), + Expanded( + child: Chat( + messages: _messages, + // onAttachmentPressed: _handleAttachmentPressed, + // onMessageTap: _handleMessageTap, + // onPreviewDataFetched: _handlePreviewDataFetched, + onSendPressed: _handleSendPressed, + showUserAvatars: false, + showUserNames: false, + user: _user, + theme: getChatTheme(), + ), + ) + ], + ), + ); + } +}